package com.jevons.geo_lib.geo_op;

import android.annotation.SuppressLint;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.jevons.geo_lib.R;
import com.jevons.geo_lib.geojson.MapboxJsonHelper;
import com.jevons.geo_lib.helper.GeometryHelper;
import com.jevons.geo_lib.op_history.BianjieCommonHistory;
import com.jevons.geo_lib.op_history.BianjieHistory;
import com.jevons.geo_lib.op_history.HuizhiHistory;
import com.jevons.geo_lib.op_history.OperationHistory;
import com.jevons.geo_lib.op_history.WakongHistory;
import com.jevons.geo_lib.utils.StringUtils;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.LineString;
import com.mapbox.geojson.MultiLineString;
import com.mapbox.geojson.MultiPoint;
import com.mapbox.geojson.MultiPolygon;
import com.mapbox.geojson.Point;
import com.mapbox.geojson.Polygon;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.plugins.annotation.Symbol;
import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager;
import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.observers.DefaultObserver;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.schedulers.Schedulers;


/**
 * Copyright 2020 JxGIS
 *
 * @file GeometryOperationHandler
 * @auth linaisheng
 * Created on 2023/12/28.
 * Description：
 */
public class GeometrySymbolHandler {

    //地图打点
    public static final String ICON_MAP_POINT = "icon_map_point";
    public static final String ICON_MAP_POINT_ADD = "icon_map_point_add";


    public static final String KEY_SYMBOL_TYPE = "symbolType";
    public static final int TYPE_SYMBOL_POINT = 0;
    public static final int TYPE_SYMBOL_POINT_ADD = 1;

    private GeometryOpManager opManager;

    //公共点
    private CommonPointHelper commonPointHelper;

    private SymbolManager symbolManager;
    private List<Symbol> symbolList;
    private List<Symbol> addPointSymbolList = new ArrayList<>();

    public GeometrySymbolHandler(GeometryOpManager opManager, SymbolManager symbolManager) {
        this.opManager = opManager;

        this.symbolManager = symbolManager;
        this.symbolManager.setIconIgnorePlacement(true);
        this.symbolManager.addDragListener(opManager);
        this.symbolManager.addLongClickListener(opManager);

        this.symbolList = new ArrayList<>();
        this.commonPointHelper = new CommonPointHelper(opManager.KEY_FEATURE_ID);
    }

    public void addPointImage(Style loadStyle, Resources resources) {
        loadStyle.addImage(ICON_MAP_POINT,
                Bitmap.createBitmap(BitmapFactory.decodeResource(
                        resources, R.mipmap.icon_map_point)));
        loadStyle.addImage(ICON_MAP_POINT_ADD,
                Bitmap.createBitmap(BitmapFactory.decodeResource(
                        resources, R.mipmap.icon_map_point_add)));
    }

    private Feature getEditFeature(String id) {
        return opManager.getEditFeature(id);
    }

    private String getFeatureIdKey() {
        return opManager.KEY_FEATURE_ID;
    }

    //绘制-添加点
    void addPointSymbolOnHuizhi(
            GeometryOpManager.OpGeometryType geometryType, List<Point> storePointList, Point addPoint) {
        JsonObject jsonData = new JsonObject();
        jsonData.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT);
        jsonData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, storePointList.size() - 1);
        symbolList.add(createSymbol(ICON_MAP_POINT, new LatLng(addPoint.latitude(), addPoint.longitude()), jsonData));

        if (geometryType == GeometryOpManager.OpGeometryType.Polygon) {
            if (storePointList.size() == 3) {
                for (int i = 0; i < storePointList.size(); i++) {
                    Point firstPoint = storePointList.get(i);
                    Point nextPoint = null;
                    if (i == 2) {
                        nextPoint = storePointList.get(0);
                    } else {
                        nextPoint = storePointList.get(i + 1);
                    }
                    Point centerPoint = Point.fromLngLat(
                            (firstPoint.longitude() + nextPoint.longitude()) / 2,
                            (firstPoint.latitude() + nextPoint.latitude()) / 2);
                    JsonObject addPointData = new JsonObject();
                    addPointData.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                    addPointData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(i + 1));

                    addPointSymbolList.add(createSymbol(
                            ICON_MAP_POINT_ADD, new LatLng(centerPoint.latitude(), centerPoint.longitude()), addPointData));
                }
            } else if (storePointList.size() > 3) {
                //更新上一个symbol
                Symbol preAddSymbol = addPointSymbolList.get(addPointSymbolList.size() - 1);
                Point prePoint = storePointList.get(storePointList.size() - 2);
                Point point = storePointList.get(storePointList.size() - 1);
                Point updatePoint = Point.fromLngLat(
                        (prePoint.longitude() + point.longitude()) / 2,
                        (prePoint.latitude() + point.latitude()) / 2);
                preAddSymbol.setLatLng(new LatLng(updatePoint.latitude(), updatePoint.longitude()));
                updateSymbol(preAddSymbol);


                Point firstPoint = storePointList.get(0);
                Point centerPoint = Point.fromLngLat(
                        (firstPoint.longitude() + point.longitude()) / 2,
                        (firstPoint.latitude() + point.latitude()) / 2);

                JsonObject addPointData = new JsonObject();
                addPointData.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                addPointData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(storePointList.size()));

                addPointSymbolList.add(createSymbol(ICON_MAP_POINT_ADD,
                        new LatLng(centerPoint.latitude(), centerPoint.longitude()), addPointData));
            }
        } else if (geometryType == GeometryOpManager.OpGeometryType.Line) {
            if (storePointList.size() > 1) {
                Point prePoint = storePointList.get(storePointList.size() - 2);
                Point point = storePointList.get(storePointList.size() - 1);
                Point centerPoint = Point.fromLngLat(
                        (prePoint.longitude() + point.longitude()) / 2,
                        (prePoint.latitude() + point.latitude()) / 2);
                JsonObject addPointData = new JsonObject();
                addPointData.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                addPointData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(storePointList.size() - 1));

                addPointSymbolList.add(createSymbol(ICON_MAP_POINT_ADD,
                        new LatLng(centerPoint.latitude(), centerPoint.longitude()), addPointData));
            }
        }
    }

    void addPointSymbolOnWakong(String targetFeatureId, List<Point> storePointList, Point addPoint) {

        JsonObject jsonData = new JsonObject();
        jsonData.addProperty(getFeatureIdKey(), targetFeatureId);
        jsonData.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT);
        jsonData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, storePointList.size() - 1);
        symbolList.add(createSymbol(ICON_MAP_POINT,
                new LatLng(addPoint.latitude(), addPoint.longitude()), jsonData));

        if (storePointList.size() == 3) {
            for (int i = 0; i < storePointList.size(); i++) {
                Point firstPoint = storePointList.get(i);
                Point nextPoint = null;
                if (i == 2) {
                    nextPoint = storePointList.get(0);
                } else {
                    nextPoint = storePointList.get(i + 1);
                }
                Point centerPoint = Point.fromLngLat(
                        (firstPoint.longitude() + nextPoint.longitude()) / 2,
                        (firstPoint.latitude() + nextPoint.latitude()) / 2);
                JsonObject addPointData = new JsonObject();
                addPointData.addProperty(getFeatureIdKey(), targetFeatureId);
                addPointData.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                addPointData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(i + 1));
                addPointSymbolList.add(createSymbol(ICON_MAP_POINT_ADD,
                        new LatLng(centerPoint.latitude(), centerPoint.longitude()), addPointData));
            }
        } else if (storePointList.size() > 3) {
            //更新上一个symbol
            Symbol preAddSymbol = addPointSymbolList.get(addPointSymbolList.size() - 1);
            Point prePoint = storePointList.get(storePointList.size() - 2);
            Point point = storePointList.get(storePointList.size() - 1);
            Point updatePoint = Point.fromLngLat(
                    (prePoint.longitude() + point.longitude()) / 2,
                    (prePoint.latitude() + point.latitude()) / 2);
            preAddSymbol.setLatLng(new LatLng(updatePoint.latitude(), updatePoint.longitude()));
            updateSymbol(preAddSymbol);


            Point firstPoint = storePointList.get(0);
            Point centerPoint = Point.fromLngLat(
                    (firstPoint.longitude() + point.longitude()) / 2,
                    (firstPoint.latitude() + point.latitude()) / 2);

            JsonObject addPointData = new JsonObject();
            addPointData.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
            addPointData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(storePointList.size()));

            addPointSymbolList.add(createSymbol(ICON_MAP_POINT_ADD,
                    new LatLng(centerPoint.latitude(), centerPoint.longitude()), addPointData));
        }

    }


    //绘制-插入点
    void insertSymbolPointOnHuizhi(List<Point> storePointList, int insertIndex, Point insertPoint) {
        for (int i = 0; i < symbolList.size(); i++) {
            Symbol symbol = symbolList.get(i);
            JsonObject jsonObject = (JsonObject) symbol.getData();
            int index = Integer.parseInt(jsonObject.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
            if (index >= insertIndex) {
                jsonObject.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(i + 1));
            }
        }

        for (int i = 0; i < addPointSymbolList.size(); i++) {
            Symbol symbol = addPointSymbolList.get(i);
            JsonObject jsonObject = (JsonObject) symbol.getData();
            int index = Integer.parseInt(jsonObject.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
            if (index > insertIndex) {
                jsonObject.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(index + 1));
            }
        }
        doTimeObservable(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) throws Exception {
                JsonObject jsonData = new JsonObject();
                jsonData.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT);
                jsonData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(insertIndex));
                symbolList.add(createSymbol(ICON_MAP_POINT,
                        new LatLng(insertPoint.latitude(), insertPoint.longitude()), jsonData));

                //更新annotation到线中心点
                Point updateLineCenterPoint = null;
                Point newLineCenterPoint = null;


                Point prePoint = storePointList.get(insertIndex - 1);
                Point nextPoint = null;
                if (insertIndex + 1 < storePointList.size()) {
                    nextPoint = storePointList.get(insertIndex + 1);
                } else {
                    nextPoint = storePointList.get(0);
                }
                updateLineCenterPoint = Point.fromLngLat((prePoint.longitude() + insertPoint.longitude()) / 2,
                        (prePoint.latitude() + insertPoint.latitude()) / 2);

                for (Symbol symbol : addPointSymbolList) {
                    JsonObject jsonObject = (JsonObject) symbol.getData();
                    int index = Integer.parseInt(jsonObject.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
                    if (index == insertIndex) {
                        symbol.setLatLng(new LatLng(updateLineCenterPoint.latitude(), updateLineCenterPoint.longitude()));
                        updateSymbol(symbol);
                    }
                }


                newLineCenterPoint = Point.fromLngLat((nextPoint.longitude() + insertPoint.longitude()) / 2,
                        (nextPoint.latitude() + insertPoint.latitude()) / 2);


                JsonObject addPointData = new JsonObject();
                addPointData.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                addPointData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(insertIndex + 1));


                addPointSymbolList.add(createSymbol(ICON_MAP_POINT_ADD,
                        new LatLng(newLineCenterPoint.latitude(), newLineCenterPoint.longitude()), addPointData));
            }
        });

    }

    void insertSymbolPointOnWakong(String targetFeatureId, List<Point> storePointList, int insertIndex, Point insertPoint) {
        for (int i = 0; i < symbolList.size(); i++) {
            Symbol symbol = symbolList.get(i);
            JsonObject jsonObject = (JsonObject) symbol.getData();
            int index = Integer.parseInt(jsonObject.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
            if (index >= insertIndex) {
                jsonObject.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(i + 1));
            }
        }

        for (int i = 0; i < addPointSymbolList.size(); i++) {
            Symbol symbol = addPointSymbolList.get(i);
            JsonObject jsonObject = (JsonObject) symbol.getData();
            int index = Integer.parseInt(jsonObject.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
            if (index > insertIndex) {
                jsonObject.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(index + 1));
            }
        }
        doTimeObservable(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) throws Exception {
                JsonObject jsonData = new JsonObject();
                jsonData.addProperty(getFeatureIdKey(), targetFeatureId);
                jsonData.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT);
                jsonData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(insertIndex));
                symbolList.add(createSymbol(ICON_MAP_POINT,
                        new LatLng(insertPoint.latitude(), insertPoint.longitude()), jsonData));

                //更新annotation到线中心点
                Point updateLineCenterPoint = null;
                Point newLineCenterPoint = null;


                Point prePoint = storePointList.get(insertIndex - 1);
                Point nextPoint = null;
                if (insertIndex + 1 < storePointList.size()) {
                    nextPoint = storePointList.get(insertIndex + 1);
                } else {
                    nextPoint = storePointList.get(0);
                }
                updateLineCenterPoint = Point.fromLngLat((prePoint.longitude() + insertPoint.longitude()) / 2,
                        (prePoint.latitude() + insertPoint.latitude()) / 2);

                for (Symbol symbol : addPointSymbolList) {
                    JsonObject jsonObject = (JsonObject) symbol.getData();
                    int index = Integer.parseInt(jsonObject.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
                    if (index == insertIndex) {
                        symbol.setLatLng(new LatLng(updateLineCenterPoint.latitude(), updateLineCenterPoint.longitude()));
                        updateSymbol(symbol);
                    }
                }


                newLineCenterPoint = Point.fromLngLat((nextPoint.longitude() + insertPoint.longitude()) / 2,
                        (nextPoint.latitude() + insertPoint.latitude()) / 2);


                JsonObject addPointData = new JsonObject();
                addPointData.addProperty(getFeatureIdKey(), targetFeatureId);
                addPointData.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                addPointData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(insertIndex + 1));

                Symbol addSymbol = createSymbol(ICON_MAP_POINT_ADD,
                        new LatLng(newLineCenterPoint.latitude(), newLineCenterPoint.longitude()), addPointData);
                addPointSymbolList.add(addSymbol);
            }
        });

    }


    void updateGeometryHuizhiMovePoint(List<Point> storePointList, int pointIndex, Point movePoint, boolean updatePointSymbol) {
        doTimeObservable(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) throws Exception {
                if (updatePointSymbol) {
                    for (Symbol symbol : symbolList) {
                        JsonObject jsonObject = (JsonObject) symbol.getData();
                        String indexStr = jsonObject.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString();
                        if (pointIndex == Integer.parseInt(indexStr)) {
                            symbol.setLatLng(new LatLng(movePoint.latitude(), movePoint.longitude()));
                            updateSymbol(symbol);
                        }
                    }
                }
                for (Symbol symbol : addPointSymbolList) {
                    JsonObject jsonObject = (JsonObject) symbol.getData();
                    String indexStr = jsonObject.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString();
                    if (pointIndex == Integer.parseInt(indexStr)) {
                        Point prePoint = storePointList.get(pointIndex - 1);
                        Point centerPoint = Point.fromLngLat(
                                (prePoint.longitude() + movePoint.longitude()) / 2,
                                (prePoint.latitude() + movePoint.latitude()) / 2);
                        symbol.setLatLng(new LatLng(centerPoint.latitude(), centerPoint.longitude()));
                        updateSymbol(symbol);
                    } else if ((pointIndex + 1) == Integer.parseInt(indexStr)) {
                        Point nextPoint;
                        if (pointIndex + 1 < storePointList.size()) {
                            nextPoint = storePointList.get(pointIndex + 1);
                        } else {
                            nextPoint = storePointList.get(0);
                        }
                        Point centerPoint = Point.fromLngLat(
                                (nextPoint.longitude() + movePoint.longitude()) / 2,
                                (nextPoint.latitude() + movePoint.latitude()) / 2);
                        symbol.setLatLng(new LatLng(centerPoint.latitude(), centerPoint.longitude()));
                        updateSymbol(symbol);
                    } else if (pointIndex == 0 && Integer.parseInt(indexStr) == addPointSymbolList.size()) {
                        Point prePoint = storePointList.get(storePointList.size() - 1);
                        Point centerPoint = Point.fromLngLat(
                                (prePoint.longitude() + movePoint.longitude()) / 2,
                                (prePoint.latitude() + movePoint.latitude()) / 2);
                        symbol.setLatLng(new LatLng(centerPoint.latitude(), centerPoint.longitude()));
                        updateSymbol(symbol);
                    }
                }
            }
        });
    }

    void updateGeometryWakongMovePoint(List<Point> storePointList, int pointIndex, Point movePoint, boolean updatePointSymbol) {
        doTimeObservable(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) throws Exception {
                if (updatePointSymbol) {
                    for (Symbol symbol : symbolList) {
                        JsonObject jsonObject = (JsonObject) symbol.getData();
                        String indexStr = jsonObject.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString();
                        if (pointIndex == Integer.parseInt(indexStr)) {
                            symbol.setLatLng(new LatLng(movePoint.latitude(), movePoint.longitude()));
                            updateSymbol(symbol);
                        }
                    }
                }
                for (Symbol symbol : addPointSymbolList) {
                    JsonObject jsonObject = (JsonObject) symbol.getData();
                    String indexStr = jsonObject.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString();
                    if (pointIndex == Integer.parseInt(indexStr)) {
                        Point prePoint = storePointList.get(pointIndex - 1);
                        Point centerPoint = Point.fromLngLat(
                                (prePoint.longitude() + movePoint.longitude()) / 2,
                                (prePoint.latitude() + movePoint.latitude()) / 2);
                        symbol.setLatLng(new LatLng(centerPoint.latitude(), centerPoint.longitude()));
                        updateSymbol(symbol);
                    } else if ((pointIndex + 1) == Integer.parseInt(indexStr)) {
                        Point nextPoint;
                        if (pointIndex + 1 < storePointList.size()) {
                            nextPoint = storePointList.get(pointIndex + 1);
                        } else {
                            nextPoint = storePointList.get(0);
                        }
                        Point centerPoint = Point.fromLngLat(
                                (nextPoint.longitude() + movePoint.longitude()) / 2,
                                (nextPoint.latitude() + movePoint.latitude()) / 2);
                        symbol.setLatLng(new LatLng(centerPoint.latitude(), centerPoint.longitude()));
                        updateSymbol(symbol);
                    } else if (pointIndex == 0 && Integer.parseInt(indexStr) == addPointSymbolList.size()) {
                        Point prePoint = storePointList.get(storePointList.size() - 1);
                        Point centerPoint = Point.fromLngLat(
                                (prePoint.longitude() + movePoint.longitude()) / 2,
                                (prePoint.latitude() + movePoint.latitude()) / 2);
                        symbol.setLatLng(new LatLng(centerPoint.latitude(), centerPoint.longitude()));
                        updateSymbol(symbol);
                    }
                }
            }
        });
    }


    void undoHuizhiAddPointOp(
            HuizhiHistory huizhiHistory, GeometryOpManager.OpGeometryType geometryType,
            List<Point> storePointList) {
        Iterator<Symbol> symbolIterator = symbolList.iterator();
        while (symbolIterator.hasNext()) {
            Symbol symbol = symbolIterator.next();
            JsonObject jsonObject = (JsonObject) symbol.getData();
            int index = Integer.parseInt(jsonObject.getAsJsonPrimitive(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
            if (huizhiHistory.getPointIndex() == index) {
                symbolIterator.remove();
                symbolManager.delete(symbol);
            }
        }

        if (geometryType == GeometryOpManager.OpGeometryType.Polygon) {
            if (storePointList.size() > 2) {
                Iterator<Symbol> addSymbolIterator = addPointSymbolList.iterator();
                while (addSymbolIterator.hasNext()) {
                    Symbol symbol = addSymbolIterator.next();
                    JsonObject jsonObject = (JsonObject) symbol.getData();
                    int index = Integer.parseInt(jsonObject.getAsJsonPrimitive(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
                    if (index == huizhiHistory.getPointIndex()) {
                        //更新坐标
                        Point firstPoint = storePointList.get(0);
                        Point endPoint = storePointList.get(storePointList.size() - 1);

                        Point updatePoint = Point.fromLngLat(
                                (firstPoint.longitude() + endPoint.longitude()) / 2,
                                (firstPoint.latitude() + endPoint.latitude()) / 2);
                        symbol.setLatLng(new LatLng(updatePoint.latitude(), updatePoint.longitude()));
                        updateSymbol(symbol);
                    } else if (index == huizhiHistory.getPointIndex() + 1) {
                        addSymbolIterator.remove();
                        symbolManager.delete(symbol);
                    }
                }
            } else {
                symbolManager.delete(addPointSymbolList);
                addPointSymbolList.clear();
            }
        } else if (geometryType == GeometryOpManager.OpGeometryType.Line) {
            if (storePointList.size() > 1) {
                Iterator<Symbol> addSymbolIterator = addPointSymbolList.iterator();
                while (addSymbolIterator.hasNext()) {
                    Symbol symbol = addSymbolIterator.next();
                    JsonObject jsonObject = (JsonObject) symbol.getData();
                    int index = Integer.parseInt(jsonObject.getAsJsonPrimitive(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
                    if (huizhiHistory.getPointIndex() == index) {
                        addSymbolIterator.remove();
                        symbolManager.delete(symbol);
                    }
                }
            } else {
                symbolManager.delete(addPointSymbolList);
                addPointSymbolList.clear();
            }
        } else if (geometryType == GeometryOpManager.OpGeometryType.Point) {
            Point prePoint = huizhiHistory.getOldPoint();
            storePointList.add(prePoint);
            JsonObject jsonData = new JsonObject();
            jsonData.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT);
            jsonData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, storePointList.size() - 1);
            Symbol preSymbol = createSymbol(ICON_MAP_POINT, new LatLng(prePoint.latitude(), prePoint.longitude()), jsonData);
            symbolList.add(preSymbol);
        }
    }

    void undoHuizhiInsertPoitOp(List<Point> storePointList, int pointIndex) {
        Iterator<Symbol> iterator = symbolList.iterator();
        while (iterator.hasNext()) {
            Symbol symbol = iterator.next();
            JsonObject jsonObject = (JsonObject) symbol.getData();
            int index = Integer.parseInt(jsonObject.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
            if (index == pointIndex) {
                iterator.remove();
                symbolManager.delete(symbol);
            } else if (index > pointIndex) {
                jsonObject.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(index - 1));
            }
        }
        Iterator<Symbol> addIterator = addPointSymbolList.iterator();
        while (addIterator.hasNext()) {
            Symbol symbol = addIterator.next();
            JsonObject jsonObject = (JsonObject) symbol.getData();
            int index = Integer.parseInt(jsonObject.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
            if (index == pointIndex) {
                addIterator.remove();
                symbolManager.delete(symbol);
            } else if (index > pointIndex) {
                jsonObject.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(index - 1));
                if (index == pointIndex + 1) {
                    Point prePoint = storePointList.get(pointIndex - 1);
                    Point point;
                    if (pointIndex < storePointList.size()) {
                        point = storePointList.get(pointIndex);
                    } else {
                        point = storePointList.get(0);
                    }

                    Point centerPoint = Point.fromLngLat(
                            (prePoint.longitude() + point.longitude()) / 2,
                            (prePoint.latitude() + point.latitude()) / 2);
                    symbol.setLatLng(new LatLng(centerPoint.latitude(), centerPoint.longitude()));
                    updateSymbol(symbol);
                }
            }
        }
    }

    void undoWakongAddPointOp(WakongHistory wakongHistory, List<Point> storePointList) {
        Iterator<Symbol> symbolIterator = symbolList.iterator();
        while (symbolIterator.hasNext()) {
            Symbol symbol = symbolIterator.next();
            JsonObject jsonObject = (JsonObject) symbol.getData();
            int index = Integer.parseInt(jsonObject.getAsJsonPrimitive(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
            if (wakongHistory.getPointIndex() == index) {
                symbolIterator.remove();
                symbolManager.delete(symbol);
            }
        }

        if (storePointList.size() > 2) {
            Iterator<Symbol> addSymbolIterator = addPointSymbolList.iterator();
            while (addSymbolIterator.hasNext()) {
                Symbol symbol = addSymbolIterator.next();
                JsonObject jsonObject = (JsonObject) symbol.getData();
                int index = Integer.parseInt(jsonObject.getAsJsonPrimitive(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
                if (index == wakongHistory.getPointIndex()) {
                    //更新坐标
                    Point firstPoint = storePointList.get(0);
                    Point endPoint = storePointList.get(storePointList.size() - 1);

                    Point updatePoint = Point.fromLngLat(
                            (firstPoint.longitude() + endPoint.longitude()) / 2,
                            (firstPoint.latitude() + endPoint.latitude()) / 2);
                    symbol.setLatLng(new LatLng(updatePoint.latitude(), updatePoint.longitude()));
                    updateSymbol(symbol);
                } else if (index == wakongHistory.getPointIndex() + 1) {
                    addSymbolIterator.remove();
                    symbolManager.delete(symbol);
                }
            }
        } else {
            symbolManager.delete(addPointSymbolList);
            addPointSymbolList.clear();
        }
    }

    void undoWakongInsertPoitOp(List<Point> storePointList, int pointIndex) {
        Iterator<Symbol> iterator = symbolList.iterator();
        while (iterator.hasNext()) {
            Symbol symbol = iterator.next();
            JsonObject jsonObject = (JsonObject) symbol.getData();
            int index = Integer.parseInt(jsonObject.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
            if (index == pointIndex) {
                iterator.remove();
                symbolManager.delete(symbol);
            } else if (index > pointIndex) {
                jsonObject.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(index - 1));
            }
        }
        Iterator<Symbol> addIterator = addPointSymbolList.iterator();
        while (addIterator.hasNext()) {
            Symbol symbol = addIterator.next();
            JsonObject jsonObject = (JsonObject) symbol.getData();
            int index = Integer.parseInt(jsonObject.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
            if (index == pointIndex) {
                addIterator.remove();
                symbolManager.delete(symbol);
            } else if (index > pointIndex) {
                jsonObject.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(index - 1));
                if (index == pointIndex + 1) {
                    Point prePoint = storePointList.get(pointIndex - 1);
                    Point point;
                    if (pointIndex < storePointList.size()) {
                        point = storePointList.get(pointIndex);
                    } else {
                        point = storePointList.get(0);
                    }

                    Point centerPoint = Point.fromLngLat(
                            (prePoint.longitude() + point.longitude()) / 2,
                            (prePoint.latitude() + point.latitude()) / 2);
                    symbol.setLatLng(new LatLng(centerPoint.latitude(), centerPoint.longitude()));
                    updateSymbol(symbol);
                }
            }
        }
    }

    void addBianjieFeatureSymbolPoint(Feature feature, OnAddBianjieFeatureSymbolPointListener listener) {
        Observable.create(new ObservableOnSubscribe<SymbolOptions>() {
            @Override
            public void subscribe(ObservableEmitter<SymbolOptions> emitter) throws Exception {
                if (feature.geometry() instanceof MultiPolygon) {
                    MultiPolygon multiPolygon = (MultiPolygon) feature.geometry();

                    for (int i = 0; i < multiPolygon.coordinates().size(); i++) {
                        List<List<Point>> pointsList = multiPolygon.coordinates().get(i);
                        for (int j = 0; j < pointsList.size(); j++) {
                            List<Point> points = pointsList.get(j);
                            for (int k = 1; k < points.size(); k++) {
                                Point point = points.get(k);

                                JsonObject data = new JsonObject();
                                data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT);
                                data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, i + "-" + j + "-" + k);
                                String tempId = feature.getStringProperty(getFeatureIdKey());
                                data.addProperty(getFeatureIdKey(), tempId);

                                SymbolOptions options = createSymbolOptions(
                                        ICON_MAP_POINT, new LatLng(point.latitude(), point.longitude()), data);
                                emitter.onNext(options);

                            }
                        }
                    }
                } else if (feature.geometry() instanceof Polygon) {
                    Polygon polygon = (Polygon) feature.geometry();

                    for (int i = 0; i < polygon.coordinates().size(); i++) {
                        List<Point> points = polygon.coordinates().get(i);
                        for (int j = 1; j < points.size(); j++) {
                            Point point = points.get(j);

                            JsonObject data = new JsonObject();
                            data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT);
                            data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, i + "-" + j);
                            String tempId = feature.getStringProperty(getFeatureIdKey());
                            data.addProperty(getFeatureIdKey(), tempId);

                            SymbolOptions options = createSymbolOptions(
                                    ICON_MAP_POINT, new LatLng(point.latitude(), point.longitude()), data);
                            emitter.onNext(options);
                        }
                    }
                } else if (feature.geometry() instanceof MultiLineString) {
                    MultiLineString multiLineString = (MultiLineString) feature.geometry();
                    for (int i = 0; i < multiLineString.coordinates().size(); i++) {
                        List<Point> points = multiLineString.coordinates().get(i);
                        for (int j = 0; j < points.size(); j++) {
                            Point point = points.get(j);

                            JsonObject data = new JsonObject();
                            data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, i + "-" + j);
                            String tempId = feature.getStringProperty(getFeatureIdKey());
                            data.addProperty(getFeatureIdKey(), tempId);

                            SymbolOptions options = createSymbolOptions(
                                    ICON_MAP_POINT, new LatLng(point.latitude(), point.longitude()), data);
                            emitter.onNext(options);
                        }
                    }
                } else if (feature.geometry() instanceof LineString) {
                    LineString lineString = (LineString) feature.geometry();
                    for (int i = 0; i < lineString.coordinates().size(); i++) {
                        Point point = lineString.coordinates().get(i);

                        JsonObject data = new JsonObject();
                        data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT);
                        data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(i));
                        String tempId = feature.getStringProperty(getFeatureIdKey());
                        data.addProperty(getFeatureIdKey(), tempId);

                        SymbolOptions options = createSymbolOptions(
                                ICON_MAP_POINT, new LatLng(point.latitude(), point.longitude()), data);
                        emitter.onNext(options);
                    }
                } else if (feature.geometry() instanceof MultiPoint) {
                    MultiPoint multiPoint = (MultiPoint) feature.geometry();
                    for (int i = 0; i < multiPoint.coordinates().size(); i++) {
                        Point point = multiPoint.coordinates().get(i);

                        JsonObject data = new JsonObject();
                        data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT);
                        data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(i));
                        String tempId = feature.getStringProperty(getFeatureIdKey());
                        data.addProperty(getFeatureIdKey(), tempId);

                        SymbolOptions options = createSymbolOptions(ICON_MAP_POINT, new LatLng(point.latitude(), point.longitude()), data);
                        emitter.onNext(options);
                    }
                } else if (feature.geometry() instanceof Point) {
                    Point point = (Point) feature.geometry();

                    JsonObject data = new JsonObject();
                    data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT);
                    data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, "0");
                    String tempId = feature.getStringProperty(getFeatureIdKey());
                    data.addProperty(getFeatureIdKey(), tempId);

                    SymbolOptions options = createSymbolOptions(
                            ICON_MAP_POINT, new LatLng(point.latitude(), point.longitude()), data);
                    emitter.onNext(options);
                }
                emitter.onComplete();
            }
        }).subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new DefaultObserver<SymbolOptions>() {
                    @Override
                    public void onNext(SymbolOptions point) {
                        Symbol symbol = symbolManager.create(point);
                        symbolList.add(symbol);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {
                        //查询相交的小班
                        if (listener != null) {
                            listener.onLoadSuccess();
                        }
                    }
                });

        Observable.create(new ObservableOnSubscribe<SymbolOptions>() {
            @Override
            public void subscribe(ObservableEmitter<SymbolOptions> emitter) throws Exception {
                if (feature.geometry() instanceof MultiPolygon) {
                    MultiPolygon multiPolygon = (MultiPolygon) feature.geometry();

                    for (int i = 0; i < multiPolygon.coordinates().size(); i++) {
                        List<List<Point>> pointsList = multiPolygon.coordinates().get(i);
                        for (int j = 0; j < pointsList.size(); j++) {
                            List<Point> points = pointsList.get(j);
                            for (int k = 1; k < points.size(); k++) {

                                Point prePoint = points.get(k - 1);
                                Point point = points.get(k);
                                Point centerPoint = Point.fromLngLat(
                                        (prePoint.longitude() + point.longitude()) / 2,
                                        (prePoint.latitude() + point.latitude()) / 2);

                                JsonObject data = new JsonObject();
                                data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                                data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, i + "-" + j + "-" + k);
                                String tempId = feature.getStringProperty(getFeatureIdKey());
                                data.addProperty(getFeatureIdKey(), tempId);

                                SymbolOptions options = createSymbolOptions(
                                        ICON_MAP_POINT_ADD, new LatLng(centerPoint.latitude(), centerPoint.longitude()), data);
                                emitter.onNext(options);

                            }
                        }
                    }
                }
                if (feature.geometry() instanceof Polygon) {
                    Polygon polygon = (Polygon) feature.geometry();

                    for (int i = 0; i < polygon.coordinates().size(); i++) {
                        List<Point> points = polygon.coordinates().get(i);
                        for (int j = 1; j < points.size(); j++) {
                            Point prePoint = points.get(j - 1);
                            Point point = points.get(j);
                            Point centerPoint = Point.fromLngLat(
                                    (prePoint.longitude() + point.longitude()) / 2,
                                    (prePoint.latitude() + point.latitude()) / 2);

                            JsonObject data = new JsonObject();
                            data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                            data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, i + "-" + j);
                            String tempId = feature.getStringProperty(getFeatureIdKey());
                            data.addProperty(getFeatureIdKey(), tempId);

                            SymbolOptions options = createSymbolOptions(
                                    ICON_MAP_POINT_ADD, new LatLng(centerPoint.latitude(), centerPoint.longitude()), data);
                            emitter.onNext(options);
                        }
                    }
                } else if (feature.geometry() instanceof MultiLineString) {
                    MultiLineString multiLineString = (MultiLineString) feature.geometry();

                    for (int i = 0; i < multiLineString.coordinates().size(); i++) {
                        List<Point> points = multiLineString.coordinates().get(i);
                        for (int j = 1; j < points.size(); j++) {
                            Point prePoint = points.get(j - 1);
                            Point point = points.get(j);
                            Point centerPoint = Point.fromLngLat(
                                    (prePoint.longitude() + point.longitude()) / 2,
                                    (prePoint.latitude() + point.latitude()) / 2);

                            JsonObject data = new JsonObject();
                            data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                            data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, i + "-" + j);
                            String tempId = feature.getStringProperty(getFeatureIdKey());
                            data.addProperty(getFeatureIdKey(), tempId);

                            SymbolOptions options = createSymbolOptions(
                                    ICON_MAP_POINT_ADD, new LatLng(centerPoint.latitude(), centerPoint.longitude()), data);
                            emitter.onNext(options);
                        }
                    }
                } else if (feature.geometry() instanceof LineString) {
                    LineString lineString = (LineString) feature.geometry();
                    List<Point> points = lineString.coordinates();
                    for (int i = 1; i < points.size(); i++) {
                        Point prePoint = points.get(i - 1);
                        Point point = points.get(i);
                        Point centerPoint = Point.fromLngLat(
                                (prePoint.longitude() + point.longitude()) / 2,
                                (prePoint.latitude() + point.latitude()) / 2);

                        JsonObject data = new JsonObject();
                        data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                        data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(i));
                        String tempId = feature.getStringProperty(getFeatureIdKey());
                        data.addProperty(getFeatureIdKey(), tempId);

                        SymbolOptions options = createSymbolOptions(
                                ICON_MAP_POINT_ADD, new LatLng(centerPoint.latitude(), centerPoint.longitude()), data);
                        emitter.onNext(options);
                    }
                }
                emitter.onComplete();
            }
        }).subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new DefaultObserver<SymbolOptions>() {
                    @Override
                    public void onNext(SymbolOptions point) {
                        Symbol symbol = symbolManager.create(point);
                        addPointSymbolList.add(symbol);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });


    }


    void checkBianjieBoundaryFeatureCommonPoint(Feature mainFeature, List<Feature> featureCollection) {
        //检查公共点
        Map<String, String> commonMap = new HashMap<>();
        GeometryHelper geometryHelper = new GeometryHelper();
        for (Feature item : featureCollection) {
            List<Point> points = geometryHelper.getPolygonIntersects(
                    mainFeature.geometry(), item.geometry());
            for (Point point : points) {

                Symbol symbol = commonPointHelper.getSymbol(symbolList, point);
                String commonKey = StringUtils.generateId();
                if (symbol != null) {
                    JsonObject data = (JsonObject) symbol.getData();
                    //是否已经是公共边
                    if (!data.has(CommonPointHelper.COMMON_KEY)) {
                        //没有则将Feature的公共点存入库中
                        commonPointHelper.addCommonPoint(commonKey, (JsonObject) symbol.getData());
                    }
                }

                String latlng = String.format("%.7f", point.latitude())
                        + "-" + String.format("%.7f", point.longitude());
                //去除重复坐标
                if (!commonMap.containsKey(latlng)) {
                    commonMap.put(latlng, commonKey);
                }
            }
        }


        Observable.fromIterable(featureCollection)
                .compose(opManager.getBaseView().bindToLifecycle())
                .subscribe(new DisposableObserver<Feature>() {
                    @Override
                    public void onNext(Feature feature) {
                        if (feature.geometry() instanceof MultiPolygon) {
                            MultiPolygon multiPolygon = (MultiPolygon) feature.geometry();

                            for (int i = 0; i < multiPolygon.coordinates().size(); i++) {
                                List<List<Point>> pointsList = multiPolygon.coordinates().get(i);
                                for (int j = 0; j < pointsList.size(); j++) {
                                    List<Point> points = pointsList.get(j);
                                    for (int k = 1; k < points.size(); k++) {
                                        Point point = points.get(k);

                                        //判断是否是公共点
                                        String latlng = String.format("%.7f", point.latitude())
                                                + "-" + String.format("%.7f", point.longitude());

                                        String commonKey = "";
                                        if (commonMap.containsKey(latlng)) {
                                            commonKey = commonMap.get(latlng);
                                        }

                                        JsonObject data = new JsonObject();
                                        data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, i + "-" + j + "-" + k);
                                        String tempId = feature.getStringProperty(getFeatureIdKey());
                                        data.addProperty(getFeatureIdKey(), tempId);

                                        if (StringUtils.isNotEmpty(commonKey)) {
                                            //如果是公共点，进行入库
                                            commonPointHelper.addCommonPoint(commonKey, data);
                                        }
                                    }
                                }
                            }
                        } else if (feature.geometry() instanceof Polygon) {
                            Polygon polygon = (Polygon) feature.geometry();

                            for (int i = 0; i < polygon.coordinates().size(); i++) {
                                List<Point> points = polygon.coordinates().get(i);
                                for (int j = 1; j < points.size(); j++) {
                                    Point point = points.get(j);

                                    //判断是否是公共点
                                    String latlng = String.format("%.7f", point.latitude())
                                            + "-" + String.format("%.7f", point.longitude());

                                    String commonKey = "";
                                    if (commonMap.containsKey(latlng)) {
                                        commonKey = commonMap.get(latlng);
                                    }

                                    JsonObject data = new JsonObject();
                                    data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, i + "-" + j);
                                    String tempId = feature.getStringProperty(getFeatureIdKey());
                                    data.addProperty(getFeatureIdKey(), tempId);

                                    if (StringUtils.isNotEmpty(commonKey)) {
                                        //如果是公共点，进行入库
                                        commonPointHelper.addCommonPoint(commonKey, data);
                                    }
                                }
                            }
                        } else if (feature.geometry() instanceof MultiLineString) {
                            MultiLineString multiLineString = (MultiLineString) feature.geometry();

                            for (int i = 0; i < multiLineString.coordinates().size(); i++) {
                                List<Point> points = multiLineString.coordinates().get(i);
                                for (int j = 1; j < points.size(); j++) {
                                    Point point = points.get(j);

                                    //判断是否是公共点
                                    String latlng = String.format("%.7f", point.latitude())
                                            + "-" + String.format("%.7f", point.longitude());

                                    String commonKey = "";
                                    if (commonMap.containsKey(latlng)) {
                                        commonKey = commonMap.get(latlng);
                                    }

                                    JsonObject data = new JsonObject();
                                    data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, i + "-" + j);
                                    String tempId = feature.getStringProperty(getFeatureIdKey());
                                    data.addProperty(getFeatureIdKey(), tempId);

                                    if (StringUtils.isNotEmpty(commonKey)) {
                                        //如果是公共点，进行入库
                                        commonPointHelper.addCommonPoint(commonKey, data);
                                    }
                                }
                            }
                        } else if (feature.geometry() instanceof LineString) {
                            LineString lineString = (LineString) feature.geometry();

                            List<Point> points = lineString.coordinates();
                            for (int i = 1; i < points.size(); i++) {
                                Point point = points.get(i);

                                //判断是否是公共点
                                String latlng = String.format("%.7f", point.latitude())
                                        + "-" + String.format("%.7f", point.longitude());

                                String commonKey = "";
                                if (commonMap.containsKey(latlng)) {
                                    commonKey = commonMap.get(latlng);
                                }

                                JsonObject data = new JsonObject();
                                data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(i));
                                String tempId = feature.getStringProperty(getFeatureIdKey());
                                data.addProperty(getFeatureIdKey(), tempId);

                                if (StringUtils.isNotEmpty(commonKey)) {
                                    //如果是公共点，进行入库
                                    commonPointHelper.addCommonPoint(commonKey, data);
                                }
                            }

                        }
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }


    //插入点
    OperationHistory addPointDataIndexs(String targetFeatureId, int[] coordinatesIndex, Point insertPoint) {
        Map<String, ArrayList<CommonPointHelper.CommonPoint>> featureToCommonLine = checkAddPointDataIndexsOnCommonLine(targetFeatureId, coordinatesIndex, insertPoint);
        String commonKey = null;
        List<BianjieHistory> commonBianjieHistoryList = new ArrayList<>();
        if (featureToCommonLine != null && !featureToCommonLine.isEmpty()) {
            //给共边图形添加节点
            Iterator<Map.Entry<String, ArrayList<CommonPointHelper.CommonPoint>>> commonLineIterator = featureToCommonLine.entrySet().iterator();
            while (commonLineIterator.hasNext()) {
                Map.Entry<String, ArrayList<CommonPointHelper.CommonPoint>> entry = commonLineIterator.next();
                ArrayList<CommonPointHelper.CommonPoint> points = entry.getValue();
                int[] insertIndexs = points.get(points.size() - 1).getCoordinatesIndex();

                //添加到公共点存储中
                if (StringUtils.isEmpty(commonKey)) {
                    commonKey = StringUtils.generateId();
                }
                JsonObject data = new JsonObject();

                if (insertIndexs.length > 2) {
                    data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, insertIndexs[0] + "-"
                            + insertIndexs[1] + "-" + insertIndexs[2]);
                } else {
                    data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, insertIndexs[0] + "-"
                            + insertIndexs[1]);
                }
                data.addProperty(getFeatureIdKey(), entry.getKey());
                commonPointHelper.addCommonPoint(commonKey, data);

                Feature operationFeature = getEditFeature(entry.getKey());
                addGeometryPointDataIndexs(operationFeature, insertIndexs, insertPoint);

                //更新公共点坐标
                List<CommonPointHelper.CommonPoint> featurePoints = commonPointHelper.getFeatureCommonPoint(entry.getKey());
                if (points.size() > 0) {
                    for (CommonPointHelper.CommonPoint point : featurePoints) {
                        int[] pointCoordinates = point.getCoordinatesIndex();

                        if (operationFeature.geometry() instanceof MultiPolygon) {
                            int i = pointCoordinates[0];
                            int j = pointCoordinates[1];
                            int k = pointCoordinates[2];

                            if (i == insertIndexs[0] && j == insertIndexs[1]
                                    && k > insertIndexs[2]) {
                                pointCoordinates[2] = pointCoordinates[2] + 1;
                                point.setCoordinatesIndex(pointCoordinates);
                            }
                        } else if (operationFeature.geometry() instanceof Polygon) {
                            int i = pointCoordinates[0];
                            int j = pointCoordinates[1];

                            if (i == insertIndexs[0] && j > insertIndexs[1]) {
                                //大于J的索引才需要更新
                                pointCoordinates[1] = pointCoordinates[1] + 1;
                                point.setCoordinatesIndex(pointCoordinates);
                            }
                        } else if (operationFeature.geometry() instanceof MultiLineString) {
                            int i = pointCoordinates[0];
                            int j = pointCoordinates[1];

                            if (i == insertIndexs[0] && j > insertIndexs[1]) {
                                //大于J的索引才需要更新
                                pointCoordinates[1] = pointCoordinates[1] + 1;
                                point.setCoordinatesIndex(pointCoordinates);
                            }
                        } else if (operationFeature.geometry() instanceof LineString) {
                            int i = pointCoordinates[0];

                            if (i > insertIndexs[0]) {
                                //大于J的索引才需要更新
                                pointCoordinates[0] = pointCoordinates[0] + 1;
                                point.setCoordinatesIndex(pointCoordinates);
                            }
                        }
                    }

                }

                BianjieHistory history = new BianjieHistory(BianjieHistory.Type.AddPoint,
                        entry.getKey(), insertIndexs, null, insertPoint);
                commonBianjieHistoryList.add(history);
            }
        }
        BianjieHistory history = addPointDataIndexs(targetFeatureId, coordinatesIndex, insertPoint, true, commonKey);
        if (!commonBianjieHistoryList.isEmpty()) {
            commonBianjieHistoryList.add(0, history);
            return new BianjieCommonHistory(BianjieHistory.Type.AddPoint, commonBianjieHistoryList);
        } else {
            return history;
        }
    }

    //插入点
    BianjieHistory addPointDataIndexs(String targetFeatureId, int[] coordinatesIndex, Point insertPoint, boolean addSymbol, String commonKey) {
        //找到操作的Feature
        Feature operationFeature = getEditFeature(targetFeatureId);
        addGeometryPointDataIndexs(operationFeature, coordinatesIndex, insertPoint);

        //更新Symbol坐标
        for (Symbol symbol : symbolList) {
            JsonObject data = (JsonObject) symbol.getData();
            String featureId = data.get(GeometryOpManager.KEY_FEATURE_ID).getAsString();

            if (!targetFeatureId.equals(featureId)) {
                continue;
            }

            String indexStr = data.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString();
            String[] indexs = indexStr.split("-");

            int[] coordinates = new int[indexs.length];
            for (int i = 0; i < indexs.length; i++) {
                coordinates[i] = Integer.parseInt(indexs[i]);
            }


            if (coordinatesIndex.length > 2) {
                //MultiPolygon
                int i = Integer.parseInt(indexs[0]);
                int j = Integer.parseInt(indexs[1]);
                int k = Integer.parseInt(indexs[2]);

                if (i == coordinatesIndex[0] && j == coordinatesIndex[1]
                        && k >= coordinatesIndex[2]) {
                    coordinates[2] = coordinates[2] + 1;

                    data.addProperty(CommonPointHelper.KEY_POINT_INDEXS,
                            coordinates[0] + "-" + coordinates[1] + "-" + coordinates[2]);
                }

            } else if (coordinatesIndex.length > 1) {
                //Polygon
                int i = Integer.parseInt(indexs[0]);
                int j = Integer.parseInt(indexs[1]);

                if (i == coordinatesIndex[0] && j >= coordinatesIndex[1]) {
                    //大于J的索引才需要更新
                    coordinates[1] = coordinates[1] + 1;

                    data.addProperty(CommonPointHelper.KEY_POINT_INDEXS,
                            coordinates[0] + "-" + coordinates[1]);
                }
            } else if (coordinatesIndex.length > 0) {
                int i = Integer.parseInt(indexs[0]);

                if (i >= coordinatesIndex[0]) {
                    //大于J的索引才需要更新
                    coordinates[0] = coordinates[0] + 1;

                    data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(coordinates[0]));
                }
            }
            doTimeObservable(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    updateSymbol(symbol);
                }
            });
        }

        //更新Symbol
        for (Symbol symbol : addPointSymbolList) {
            JsonObject data = (JsonObject) symbol.getData();
            String featureId = data.get(getFeatureIdKey()).getAsString();

            if (!targetFeatureId.equals(featureId)) {
                continue;
            }

            String indexStr = data.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString();
            String[] indexs = indexStr.split("-");

            int[] coordinates = new int[indexs.length];
            for (int i = 0; i < indexs.length; i++) {
                coordinates[i] = Integer.parseInt(indexs[i]);
            }

            if (coordinatesIndex.length > 2) {
                //MultiPolygon
                int i = Integer.parseInt(indexs[0]);
                int j = Integer.parseInt(indexs[1]);
                int k = Integer.parseInt(indexs[2]);

                if (i == coordinatesIndex[0] && j == coordinatesIndex[1]
                        && k > coordinatesIndex[2]) {
                    coordinates[2] = coordinates[2] + 1;

                    data.addProperty(CommonPointHelper.KEY_POINT_INDEXS,
                            coordinates[0] + "-" + coordinates[1] + "-" + coordinates[2]);
                }
            } else if (coordinatesIndex.length > 1) {
                //Polygon
                int i = Integer.parseInt(indexs[0]);
                int j = Integer.parseInt(indexs[1]);
                if (i == coordinatesIndex[0] && j > coordinatesIndex[1]) {
                    //大于J的索引才需要更新
                    coordinates[1] = coordinates[1] + 1;

                    data.addProperty(CommonPointHelper.KEY_POINT_INDEXS,
                            coordinates[0] + "-" + coordinates[1]);
                }
            } else if (coordinatesIndex.length > 0) {
                //LineString
                int i = Integer.parseInt(indexs[0]);
                if (i > coordinatesIndex[0]) {
                    //大于J的索引才需要更新
                    coordinates[0] = coordinates[0] + 1;

                    data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(coordinates[0]));
                }
            }
            doTimeObservable(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    updateSymbol(symbol);
                }
            });

        }

        //更新公共点坐标
        List<CommonPointHelper.CommonPoint> points = commonPointHelper.getFeatureCommonPoint(targetFeatureId);
        if (points.size() > 0) {
            for (CommonPointHelper.CommonPoint point : points) {
                int[] pointCoordinates = point.getCoordinatesIndex();

                if (operationFeature.geometry() instanceof MultiPolygon) {
                    int i = pointCoordinates[0];
                    int j = pointCoordinates[1];
                    int k = pointCoordinates[2];

                    if (i == coordinatesIndex[0] && j == coordinatesIndex[1]
                            && k >= coordinatesIndex[2]) {
                        pointCoordinates[2] = pointCoordinates[2] + 1;
                        point.setCoordinatesIndex(pointCoordinates);
                    }
                } else if (operationFeature.geometry() instanceof Polygon) {
                    int i = pointCoordinates[0];
                    int j = pointCoordinates[1];

                    if (i == coordinatesIndex[0] && j >= coordinatesIndex[1]) {
                        //大于J的索引才需要更新
                        pointCoordinates[1] = pointCoordinates[1] + 1;
                        point.setCoordinatesIndex(pointCoordinates);
                    }
                } else if (operationFeature.geometry() instanceof MultiLineString) {
                    int i = pointCoordinates[0];
                    int j = pointCoordinates[1];

                    if (i == coordinatesIndex[0] && j >= coordinatesIndex[1]) {
                        //大于J的索引才需要更新
                        pointCoordinates[1] = pointCoordinates[1] + 1;
                        point.setCoordinatesIndex(pointCoordinates);
                    }
                } else if (operationFeature.geometry() instanceof LineString) {
                    int i = pointCoordinates[0];

                    if (i >= coordinatesIndex[0]) {
                        //大于J的索引才需要更新
                        pointCoordinates[0] = pointCoordinates[0] + 1;
                        point.setCoordinatesIndex(pointCoordinates);
                    }
                }
            }

        }

        if (addSymbol) {
            addBianjieSymbolPoint(targetFeatureId, coordinatesIndex, insertPoint, commonKey);
        }
        BianjieHistory history = new BianjieHistory(BianjieHistory.Type.AddPoint,
                targetFeatureId, coordinatesIndex, null, insertPoint);
        return history;
    }

    private void addGeometryPointDataIndexs(Feature operationFeature, int[] coordinatesIndex, Point insertPoint) {
        if (operationFeature.geometry() instanceof MultiPolygon) {
            MultiPolygon multiPolygon = (MultiPolygon) operationFeature.geometry();
            int i = coordinatesIndex[0];
            int j = coordinatesIndex[1];
            int k = coordinatesIndex[2];

            List<Point> points = multiPolygon.coordinates().get(i).get(j);

            //如果是添加最后一个
            if (k == points.size()) {
                points.add(insertPoint);
                //更新第一个点坐标与插入的相同，使其闭合
                points.set(0, insertPoint);
            } else {
                points.add(k, insertPoint);
            }
        } else if (operationFeature.geometry() instanceof Polygon) {
            Polygon polygon = (Polygon) operationFeature.geometry();
            int i = coordinatesIndex[0];
            int j = coordinatesIndex[1];

            List<Point> points = polygon.coordinates().get(i);

            //如果是添加最后一个
            if (j == points.size()) {
                points.add(insertPoint);
                //更新第一个点坐标与插入的相同，使其闭合
                points.set(0, insertPoint);
            } else {
                points.add(j, insertPoint);
            }
        } else if (operationFeature.geometry() instanceof MultiLineString) {
            MultiLineString multiLineString = (MultiLineString) operationFeature.geometry();
            int i = coordinatesIndex[0];
            int j = coordinatesIndex[1];

            List<Point> points = multiLineString.coordinates().get(i);

            points.add(j, insertPoint);
        } else if (operationFeature.geometry() instanceof LineString) {
            LineString lineString = (LineString) operationFeature.geometry();
            int i = coordinatesIndex[0];

            List<Point> points = lineString.coordinates();

            points.add(i, insertPoint);
        } else if (operationFeature.geometry() instanceof MultiPoint) {
            MultiPoint multiPoint = (MultiPoint) operationFeature.geometry();
            int i = coordinatesIndex[0];

            List<Point> points = multiPoint.coordinates();

            points.add(i, insertPoint);
        }
    }

    //检测添加的点是否在共边上
    private Map<String, ArrayList<CommonPointHelper.CommonPoint>> checkAddPointDataIndexsOnCommonLine(String targetFeatureId, int[] coordinatesIndex, Point insertPoint) {
        List<CommonPointHelper.CommonPoint> commonPoints = commonPointHelper.getFeatureCommonPoint(targetFeatureId);
        if (commonPoints.size() > 0) {
            Feature targetFeature = getEditFeature(targetFeatureId);
            CommonPointHelper.CommonPoint preCommonPoint = null;
            CommonPointHelper.CommonPoint nextCommonPoint = null;
            if (targetFeature.geometry() instanceof MultiPolygon) {
                int i = coordinatesIndex[0];
                int j = coordinatesIndex[1];
                int k = coordinatesIndex[2];


                for (CommonPointHelper.CommonPoint commonPoint : commonPoints) {
                    int[] commonCoordinatesIndex = commonPoint.getCoordinatesIndex();
                    if (i == commonCoordinatesIndex[0] && j == commonCoordinatesIndex[1]) {
                        if (k == commonCoordinatesIndex[2]) {
                            preCommonPoint = commonPoint;
                        } else if (k - 1 == commonCoordinatesIndex[2]) {
                            nextCommonPoint = commonPoint;
                        }
                    }
                }

            } else if (targetFeature.geometry() instanceof Polygon) {
                int i = coordinatesIndex[0];
                int j = coordinatesIndex[1];

                for (CommonPointHelper.CommonPoint commonPoint : commonPoints) {
                    int[] commonCoordinatesIndex = commonPoint.getCoordinatesIndex();
                    if (i == commonCoordinatesIndex[0]) {
                        if (j == commonCoordinatesIndex[1]) {
                            preCommonPoint = commonPoint;
                        } else if (j - 1 == commonCoordinatesIndex[1]) {
                            nextCommonPoint = commonPoint;
                        }
                    }
                }
            }

            if (preCommonPoint != null && nextCommonPoint != null) {
                Set<CommonPointHelper.CommonPoint> allCommonSet = new HashSet<>();
                allCommonSet.addAll(commonPointHelper
                        .getCommonPoint(preCommonPoint.getCommonKey()));
                allCommonSet.addAll(commonPointHelper
                        .getCommonPoint(nextCommonPoint.getCommonKey()));

                //按feature加下标分类后找到共边的两个点
                Map<String, Set<CommonPointHelper.CommonPoint>> featureToCommon = new HashMap<>();
                for (CommonPointHelper.CommonPoint commonPoint : allCommonSet) {
                    if (!commonPoint.getFeatureId().equals(targetFeatureId)) {
                        String featurePointIndexFlag = commonPoint.getFeatureId();
                        int[] commonCoordinatesIndexs = commonPoint.getCoordinatesIndex();
                        if (commonCoordinatesIndexs.length > 2) {
                            featurePointIndexFlag += ":" + commonCoordinatesIndexs[0] + "-" +  commonCoordinatesIndexs[1];
                        } else if (commonCoordinatesIndexs.length > 1) {
                            featurePointIndexFlag += ":" + commonCoordinatesIndexs[0];
                        }
                        Set<CommonPointHelper.CommonPoint> set = featureToCommon.get(featurePointIndexFlag);
                        if (set == null) {
                            set = new HashSet<>();
                            featureToCommon.put(featurePointIndexFlag, set);
                        }
                        set.add(commonPoint);
                    }
                }

                Map<String, ArrayList<CommonPointHelper.CommonPoint>> featureToCommonLine = new HashMap<>();
                Iterator<Map.Entry<String, Set<CommonPointHelper.CommonPoint>>> iterator = featureToCommon.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, Set<CommonPointHelper.CommonPoint>> entry = iterator.next();
                    TreeMap<Integer, CommonPointHelper.CommonPoint> commonLinePointMap = findCommonLinePoint(entry);
                    if (commonLinePointMap != null) {
                        String feature = commonLinePointMap.values().iterator().next().getFeatureId();
                        featureToCommonLine.put(feature, new ArrayList<>(commonLinePointMap.values()));
                    }
                }

                return featureToCommonLine;
            }
        }
        return null;
    }


    private TreeMap<Integer, CommonPointHelper.CommonPoint> findCommonLinePoint(Map.Entry<String, Set<CommonPointHelper.CommonPoint>> entry) {
        Set<CommonPointHelper.CommonPoint> set = entry.getValue();
        if (set.size() >= 2) {
            //只有大于等于2的才有可能存在共边
            TreeMap<Integer, CommonPointHelper.CommonPoint> map = new TreeMap<>(new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o1 - o2;
                }
            });
            for (CommonPointHelper.CommonPoint commonPoint : set) {
                int[] commonCoordinatesIndexs = commonPoint.getCoordinatesIndex();
                if (commonCoordinatesIndexs.length > 2) {
                    map.put(commonCoordinatesIndexs[2], commonPoint);
                } else if (commonCoordinatesIndexs.length > 1) {
                    map.put(commonCoordinatesIndexs[1], commonPoint);
                }
            }
            List<Integer> indexs = new ArrayList<>(map.keySet());
            Collections.sort(indexs, new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o1 - o2;
                }
            });
            for (int i = 0; i < indexs.size() - 1; i++) {
                int currentIndex = indexs.get(i);
                int preIndex = indexs.get(i + 1);
                if (currentIndex + 1 == preIndex) {
                    return map;
                }
            }
        }
        return null;
    }


    @SuppressLint("CheckResult")
    private void addBianjieSymbolPoint(String tempId, int[] coordinatesIndex, Point insertPoint, String commonKey) {
        doTimeObservable(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) throws Exception {
                Feature operationFeature = getEditFeature(tempId);

                JsonObject insertData = new JsonObject();
                insertData.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT);
                if (coordinatesIndex.length > 2) {
                    insertData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, coordinatesIndex[0] + "-"
                            + coordinatesIndex[1] + "-" + coordinatesIndex[2]);
                } else if (coordinatesIndex.length > 1) {
                    insertData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, coordinatesIndex[0] + "-"
                            + coordinatesIndex[1]);
                } else if (coordinatesIndex.length > 0) {
                    insertData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(coordinatesIndex[0]));
                }
                insertData.addProperty(getFeatureIdKey(), tempId);
                if (StringUtils.isNotEmpty(commonKey)) {
                    insertData.addProperty(CommonPointHelper.COMMON_KEY, commonKey);
                    commonPointHelper.addCommonPoint(commonKey, insertData);
                }


                Symbol symbol = createSymbol(ICON_MAP_POINT,
                        new LatLng(insertPoint.latitude(), insertPoint.longitude()), insertData);
                symbolList.add(symbol);

                //更新annotation到线中心点
                Point updateLineCenterPoint = null;
                Point newLineCenterPoint = null;
                if (operationFeature.geometry() instanceof MultiPolygon) {
                    MultiPolygon multiPolygon = (MultiPolygon) operationFeature.geometry();
                    int i = coordinatesIndex[0];
                    int j = coordinatesIndex[1];
                    int k = coordinatesIndex[2];

                    List<Point> points = multiPolygon.coordinates().get(i).get(j);
                    if (k + 1 == points.size()) {
                        //插入的点是最后一个点
                        int[] updateSymbolIndex = new int[coordinatesIndex.length];
                        updateSymbolIndex[0] = i;
                        updateSymbolIndex[1] = j;
                        updateSymbolIndex[1] = 1;

                        Point prePoint = points.get(k - 1);
                        Point nextPoint = points.get(k + 1);
                        updateLineCenterPoint = Point.fromLngLat((nextPoint.longitude() + insertPoint.longitude()) / 2,
                                (nextPoint.latitude() + insertPoint.latitude()) / 2);
                        Symbol annotation = getTargetAddPointSymbol(tempId, updateSymbolIndex);
                        if (annotation != null) {
                            annotation.setLatLng(new LatLng(updateLineCenterPoint.latitude(), updateLineCenterPoint.longitude()));
                            updateSymbol(annotation);
                        }

                        newLineCenterPoint = Point.fromLngLat((prePoint.longitude() + insertPoint.longitude()) / 2,
                                (prePoint.latitude() + insertPoint.latitude()) / 2);

                        JsonObject data = new JsonObject();
                        data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                        data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, i + "-" + j + "-" + (k + 1));
                        data.addProperty(getFeatureIdKey(), tempId);

                        addPointSymbolList.add(createSymbol(ICON_MAP_POINT_ADD,
                                new LatLng(newLineCenterPoint.latitude(), newLineCenterPoint.longitude()), data));
                    } else {
                        //插入中间点
                        Point prePoint = points.get(k - 1);
                        Point nextPoint = points.get(k + 1);
                        updateLineCenterPoint = Point.fromLngLat((prePoint.longitude() + insertPoint.longitude()) / 2,
                                (prePoint.latitude() + insertPoint.latitude()) / 2);
                        Symbol annotation = getTargetAddPointSymbol(tempId, coordinatesIndex);
                        if (annotation != null) {
                            annotation.setLatLng(new LatLng(updateLineCenterPoint.latitude(), updateLineCenterPoint.longitude()));
                            updateSymbol(annotation);
                        }

                        newLineCenterPoint = Point.fromLngLat((nextPoint.longitude() + insertPoint.longitude()) / 2,
                                (nextPoint.latitude() + insertPoint.latitude()) / 2);

                        JsonObject data = new JsonObject();
                        data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                        data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, i + "-" + j + "-" + (k + 1));
                        data.addProperty(getFeatureIdKey(), tempId);

                        addPointSymbolList.add(createSymbol(ICON_MAP_POINT_ADD,
                                new LatLng(newLineCenterPoint.latitude(), newLineCenterPoint.longitude()), data));
                    }

                } else if (operationFeature.geometry() instanceof Polygon) {
                    Polygon polygon = (Polygon) operationFeature.geometry();
                    int i = coordinatesIndex[0];
                    int j = coordinatesIndex[1];

                    List<Point> points = polygon.coordinates().get(i);

                    if (j + 1 == points.size()) {
                        //插入的点是最后一个点
                        int[] updateSymbolIndex = new int[coordinatesIndex.length];
                        updateSymbolIndex[0] = i;
                        updateSymbolIndex[1] = 1;

                        Point prePoint = points.get(j - 1);
                        Point nextPoint = points.get(1);

                        updateLineCenterPoint = Point.fromLngLat((nextPoint.longitude() + insertPoint.longitude()) / 2,
                                (nextPoint.latitude() + insertPoint.latitude()) / 2);

                        Symbol annotation = getTargetAddPointSymbol(tempId, updateSymbolIndex);
                        if (annotation != null) {
                            annotation.setLatLng(new LatLng(updateLineCenterPoint.latitude(), updateLineCenterPoint.longitude()));
                            updateSymbol(annotation);
                        }


                        newLineCenterPoint = Point.fromLngLat((prePoint.longitude() + insertPoint.longitude()) / 2,
                                (prePoint.latitude() + insertPoint.latitude()) / 2);


                        JsonObject data = new JsonObject();
                        data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                        data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, i + "-" + j);
                        data.addProperty(getFeatureIdKey(), tempId);

                        addPointSymbolList.add(createSymbol(ICON_MAP_POINT_ADD,
                                new LatLng(newLineCenterPoint.latitude(), newLineCenterPoint.longitude()), data));

                    } else {
                        //插入中间点
                        Point prePoint = points.get(j - 1);
                        Point nextPoint = points.get(j + 1);
                        updateLineCenterPoint = Point.fromLngLat((prePoint.longitude() + insertPoint.longitude()) / 2,
                                (prePoint.latitude() + insertPoint.latitude()) / 2);

                        Symbol annotation = getTargetAddPointSymbol(tempId, coordinatesIndex);
                        if (annotation != null) {
                            annotation.setLatLng(new LatLng(updateLineCenterPoint.latitude(), updateLineCenterPoint.longitude()));
                            updateSymbol(annotation);
                        }


                        newLineCenterPoint = Point.fromLngLat((nextPoint.longitude() + insertPoint.longitude()) / 2,
                                (nextPoint.latitude() + insertPoint.latitude()) / 2);


                        JsonObject data = new JsonObject();
                        data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                        data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, i + "-" + (j + 1));
                        data.addProperty(getFeatureIdKey(), tempId);

                        addPointSymbolList.add(createSymbol(ICON_MAP_POINT_ADD,
                                new LatLng(newLineCenterPoint.latitude(), newLineCenterPoint.longitude()), data));
                    }
                } else if (operationFeature.geometry() instanceof MultiLineString) {
                    MultiLineString multiLineString = (MultiLineString) operationFeature.geometry();
                    int i = coordinatesIndex[0];
                    int j = coordinatesIndex[1];

                    List<Point> points = multiLineString.coordinates().get(i);

                    if (j + 1 == points.size()) {
                        //插入中间点
                        Point prePoint = points.get(j - 1);
                        newLineCenterPoint = Point.fromLngLat((prePoint.longitude() + insertPoint.longitude()) / 2,
                                (prePoint.latitude() + insertPoint.latitude()) / 2);

                        JsonObject data = new JsonObject();
                        data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                        data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, i + "-" + j);
                        data.addProperty(getFeatureIdKey(), tempId);

                        addPointSymbolList.add(createSymbol(ICON_MAP_POINT_ADD,
                                new LatLng(newLineCenterPoint.latitude(), newLineCenterPoint.longitude()), data));
                    } else {
                        //插入中间点
                        Point prePoint = points.get(j - 1);
                        Point nextPoint = points.get(j + 1);
                        updateLineCenterPoint = Point.fromLngLat((prePoint.longitude() + insertPoint.longitude()) / 2,
                                (prePoint.latitude() + insertPoint.latitude()) / 2);

                        Symbol annotation = getTargetAddPointSymbol(tempId, coordinatesIndex);
                        if (annotation != null) {
                            annotation.setLatLng(new LatLng(updateLineCenterPoint.latitude(), updateLineCenterPoint.longitude()));
                            updateSymbol(annotation);
                        }


                        newLineCenterPoint = Point.fromLngLat((nextPoint.longitude() + insertPoint.longitude()) / 2,
                                (nextPoint.latitude() + insertPoint.latitude()) / 2);


                        JsonObject data = new JsonObject();
                        data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                        data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, i + "-" + (j + 1));
                        data.addProperty(getFeatureIdKey(), tempId);

                        addPointSymbolList.add(createSymbol(ICON_MAP_POINT_ADD,
                                new LatLng(newLineCenterPoint.latitude(), newLineCenterPoint.longitude()), data));
                    }
                } else if (operationFeature.geometry() instanceof LineString) {
                    LineString multiLineString = (LineString) operationFeature.geometry();
                    int i = coordinatesIndex[0];

                    List<Point> points = multiLineString.coordinates();

                    if (i + 1 == points.size()) {
                        Point prePoint = points.get(i - 1);
                        newLineCenterPoint = Point.fromLngLat((prePoint.longitude() + insertPoint.longitude()) / 2,
                                (prePoint.latitude() + insertPoint.latitude()) / 2);


                        JsonObject data = new JsonObject();
                        data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                        data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(i));
                        data.addProperty(getFeatureIdKey(), tempId);

                        addPointSymbolList.add(createSymbol(ICON_MAP_POINT_ADD,
                                new LatLng(newLineCenterPoint.latitude(), newLineCenterPoint.longitude()), data));
                    } else {
                        //插入中间点
                        Point prePoint = points.get(i - 1);
                        Point nextPoint = points.get(i + 1);
                        updateLineCenterPoint = Point.fromLngLat((prePoint.longitude() + insertPoint.longitude()) / 2,
                                (prePoint.latitude() + insertPoint.latitude()) / 2);

                        Symbol annotation = getTargetAddPointSymbol(tempId, coordinatesIndex);
                        if (annotation != null) {
                            annotation.setLatLng(new LatLng(updateLineCenterPoint.latitude(), updateLineCenterPoint.longitude()));
                            updateSymbol(annotation);
                        }


                        newLineCenterPoint = Point.fromLngLat((nextPoint.longitude() + insertPoint.longitude()) / 2,
                                (nextPoint.latitude() + insertPoint.latitude()) / 2);


                        JsonObject data = new JsonObject();
                        data.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT_ADD);
                        data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(i + 1));
                        data.addProperty(getFeatureIdKey(), tempId);

                        addPointSymbolList.add(createSymbol(ICON_MAP_POINT_ADD,
                                new LatLng(newLineCenterPoint.latitude(), newLineCenterPoint.longitude()), data));
                    }


                }
            }
        });
    }

    //删除点
    OperationHistory doDeleteGeometrySymbolPoint(Symbol symbol, LatLng dragStartLatlng) {

        JsonObject data = (JsonObject) symbol.getData();
        String featureId = data.get(getFeatureIdKey()).getAsString();
        String indexStr = data.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString();
        String commonKey = data.has(CommonPointHelper.COMMON_KEY) ?
                data.get(CommonPointHelper.COMMON_KEY).getAsString() : null;

        Point oldPoint;
        if (dragStartLatlng != null) {
            oldPoint = Point.fromLngLat(dragStartLatlng.getLongitude(),
                    dragStartLatlng.getLatitude());
        } else {
            oldPoint = Point.fromLngLat(symbol.getLatLng().getLongitude(),
                    symbol.getLatLng().getLatitude());
        }

        if (StringUtils.isNotEmpty(commonKey)) {
            //如果是公共点，将公共点去掉
            Set<CommonPointHelper.CommonPoint> commonSet = commonPointHelper.getCommonPoint(commonKey);

            Set<CommonPointHelper.CommonPoint> canDeleteSet = new HashSet<>();
            Set<CommonPointHelper.CommonPoint> cannotDeleteSet = new HashSet<>();
            List<BianjieHistory> deleteBianjieHistoryList = new ArrayList<>();

            if (commonSet != null) {
                Iterator<CommonPointHelper.CommonPoint> iterator = commonSet.iterator();
                while (iterator.hasNext()) {
                    CommonPointHelper.CommonPoint point = iterator.next();

                    boolean canDelete = canDeleteGeometryPointDataIndexs(point.getFeatureId(), point.getCoordinatesIndex());
                    if (canDelete) {
                        canDeleteSet.add(point);
                    } else {
                        cannotDeleteSet.add(point);
                    }

                }
            }

            int successCount = 0;
            if (cannotDeleteSet.isEmpty()) {
                //没有不可删除的共点
                for (CommonPointHelper.CommonPoint point : canDeleteSet) {
                    boolean isSuccess = deleteGeometrySymbolDataIndexs(point.getFeatureId(),
                            point.getCoordinatesIndex(), false);
                    if (isSuccess) {
                        BianjieHistory bianjieHistory = new BianjieHistory(BianjieHistory.Type.DeletePoint,
                                point.getFeatureId(), point.getCoordinatesIndex(), oldPoint);
                        bianjieHistory.setCommonKey(commonKey);
                        deleteBianjieHistoryList.add(bianjieHistory);
                        successCount++;
                    }
                }
            }

            if (canDeleteSet.size() > 0 && successCount == canDeleteSet.size()) {
                symbolList.remove(symbol);
                symbolManager.delete(symbol);

                removeCommonPoint(commonKey);

                //删除公共点历史
                BianjieCommonHistory history = new BianjieCommonHistory(BianjieHistory.Type.DeletePoint, deleteBianjieHistoryList);
                return history;
            } else {
                //删除失败

            }
        } else {
            String[] indexs = indexStr.split("-");
            int[] coordinatesIndex = new int[indexs.length];
            for (int i = 0; i < indexs.length; i++) {
                coordinatesIndex[i] = Integer.parseInt(indexs[i]);
            }
            //找出i,j这个列表下所有大于k的symbol，将索引减1
            boolean isSuccess = deleteGeometrySymbolDataIndexs(featureId, coordinatesIndex, false);

            if (isSuccess) {
                symbolList.remove(symbol);
                symbolManager.delete(symbol);

                BianjieHistory history = new BianjieHistory(BianjieHistory.Type.DeletePoint,
                        featureId, coordinatesIndex, oldPoint, null);
                return history;
            }
        }
        return null;
    }


    //删除点
    boolean deleteGeometrySymbolDataIndexs(String targetFeatureId, int[] coordinatesIndex, boolean removeTargetSymbol) {
        //找到操作的Feature
        Feature operationFeature = getEditFeature(targetFeatureId);

        if (removeTargetSymbol) {
            //找到这个Symbol
            Symbol targetSymbol = getTargetPointSymbol(targetFeatureId, coordinatesIndex);
            if (targetSymbol != null) {
                symbolList.remove(targetSymbol);
                symbolManager.delete(targetSymbol);
            }
        }

        if (operationFeature.geometry() instanceof MultiPolygon) {
            MultiPolygon multiPolygon = (MultiPolygon) operationFeature.geometry();
            int i = coordinatesIndex[0];
            int j = coordinatesIndex[1];
            int k = coordinatesIndex[2];

            List<Point> points = multiPolygon.coordinates().get(i).get(j);

            if (points.size() <= 4) {
                //不能继续删除了，不然无法构成多边形
                return false;
            }

            //如果是删除最后一个
            if (k == points.size() - 1) {
                points.remove(k);

                points.set(0, points.get(points.size() - 1));
            } else {
                points.remove(k);
            }
        } else if (operationFeature.geometry() instanceof Polygon) {
            Polygon polygon = (Polygon) operationFeature.geometry();
            int i = coordinatesIndex[0];
            int j = coordinatesIndex[1];

            List<Point> points = polygon.coordinates().get(i);

            if (points.size() <= 4) {
                //不能继续删除了，不然无法构成多边形
                return false;
            }

            //如果是删除最后一个
            if (j == points.size() - 1) {
                points.remove(j);

                points.set(0, points.get(points.size() - 1));
            } else {
                points.remove(j);
            }

        } else if (operationFeature.geometry() instanceof MultiLineString) {
            MultiLineString multiLineString = (MultiLineString) operationFeature.geometry();
            int i = coordinatesIndex[0];
            int j = coordinatesIndex[1];

            List<Point> points = multiLineString.coordinates().get(i);

            if (points.size() <= 2) {
                //不能继续删除了，不然无法构成多边形
                return false;
            }

            points.remove(j);
        } else if (operationFeature.geometry() instanceof LineString) {
            LineString lineString = (LineString) operationFeature.geometry();
            int i = coordinatesIndex[0];

            List<Point> points = lineString.coordinates();

            if (points.size() <= 2) {
                //不能继续删除了，不然无法构成多边形
                return false;
            }


            points.remove(i);
        } else if (operationFeature.geometry() instanceof MultiPoint) {
            MultiPoint multiPoint = (MultiPoint) operationFeature.geometry();
            int i = coordinatesIndex[0];

            List<Point> points = multiPoint.coordinates();

            if (points.size() <= 1) {
                //不能继续删除了，不然无法构成多边形
                return false;
            }

            points.remove(i);
        } else if (operationFeature.geometry() instanceof Point) {
            //不能继续删除了，不然无法构成多边形
            return false;
        }

        //更新Symbol坐标
        for (Symbol symbol : symbolList) {
            JsonObject data = (JsonObject) symbol.getData();
            String featureId = data.get(getFeatureIdKey()).getAsString();

            if (!targetFeatureId.equals(featureId)) {
                continue;
            }

            String indexStr = data.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString();
            String[] indexs = indexStr.split("-");

            int[] coordinates = new int[indexs.length];
            for (int i = 0; i < indexs.length; i++) {
                coordinates[i] = Integer.parseInt(indexs[i]);
            }


            if (coordinatesIndex.length > 2) {
                int i = Integer.parseInt(indexs[0]);
                int j = Integer.parseInt(indexs[1]);
                int k = Integer.parseInt(indexs[2]);

                if (i == coordinatesIndex[0] && j == coordinatesIndex[1]
                        && k > coordinatesIndex[2]) {
                    coordinates[2] = coordinates[2] - 1;

                    data.addProperty(CommonPointHelper.KEY_POINT_INDEXS,
                            coordinates[0] + "-" + coordinates[1] + "-" + coordinates[2]);
                }

            } else if (coordinatesIndex.length > 1) {
                int i = Integer.parseInt(indexs[0]);
                int j = Integer.parseInt(indexs[1]);

                if (i == coordinatesIndex[0] && j > coordinatesIndex[1]) {
                    //大于J的索引才需要更新
                    coordinates[1] = coordinates[1] - 1;

                    data.addProperty(CommonPointHelper.KEY_POINT_INDEXS,
                            coordinates[0] + "-" + coordinates[1]);
                }
            } else if (coordinatesIndex.length > 0) {
                int i = Integer.parseInt(indexs[0]);
                if (i > coordinatesIndex[0]) {
                    //大于J的索引才需要更新
                    coordinates[0] = coordinates[0] - 1;

                    data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(coordinates[0]));
                }
            }
        }

        //更新插入Symbol坐标
        List<Symbol> shouldUpdateSymbol = new ArrayList<>();
        List<Symbol> shouldRemoveSymbol = new ArrayList<>();
        for (Symbol symbol : addPointSymbolList) {
            JsonObject data = (JsonObject) symbol.getData();
            String featureId = data.get(getFeatureIdKey()).getAsString();

            if (!targetFeatureId.equals(featureId)) {
                continue;
            }

            String indexStr = data.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString();
            String[] indexs = indexStr.split("-");

            int[] coordinates = new int[indexs.length];
            for (int i = 0; i < indexs.length; i++) {
                coordinates[i] = Integer.parseInt(indexs[i]);
            }

            if (operationFeature.geometry() instanceof MultiPolygon) {
                MultiPolygon multiPolygon = (MultiPolygon) operationFeature.geometry();
                List<Point> points = multiPolygon.coordinates().get(coordinatesIndex[0]).get(coordinatesIndex[1]);

                int i = Integer.parseInt(indexs[0]);
                int j = Integer.parseInt(indexs[1]);
                int k = Integer.parseInt(indexs[2]);

                if (i == coordinatesIndex[0] && j == coordinatesIndex[1]) {
                    if (coordinatesIndex[2] == points.size() && k == 1) {
                        //删除的是最后一个，则更新第一个新增点的图标
                        shouldUpdateSymbol.add(symbol);
                    } else {
                        if (k == coordinatesIndex[2]) {
                            //删除
                            shouldRemoveSymbol.add(symbol);
                        } else if (k > coordinatesIndex[2]) {
                            if (k == coordinatesIndex[2] + 1) {
                                //更新图标位置到中线点
                                shouldUpdateSymbol.add(symbol);
                            }
                            //序号减一
                            coordinates[2] = coordinates[2] - 1;

                            data.addProperty(CommonPointHelper.KEY_POINT_INDEXS,
                                    coordinates[0] + "-" + coordinates[1] + "-" + coordinates[2]);
                        }
                    }
                }
            } else if (operationFeature.geometry() instanceof Polygon) {
                Polygon polygon = (Polygon) operationFeature.geometry();
                List<Point> points = polygon.coordinates().get(coordinatesIndex[0]);

                int i = Integer.parseInt(indexs[0]);
                int j = Integer.parseInt(indexs[1]);

                if (i == coordinatesIndex[0]) {

                    if (coordinatesIndex[1] == points.size() && j == 1) {
                        //删除的是最后一个，则更新第一个新增点的图标
                        shouldUpdateSymbol.add(symbol);
                    } else {
                        //大于J的索引才需要更新
                        if (j == coordinatesIndex[1]) {
                            shouldRemoveSymbol.add(symbol);
                        } else if (j > coordinatesIndex[1]) {
                            if (j == coordinatesIndex[1] + 1) {
                                //更新图标位置到中线点
                                shouldUpdateSymbol.add(symbol);
                            }
                            coordinates[1] = coordinates[1] - 1;

                            data.addProperty(CommonPointHelper.KEY_POINT_INDEXS,
                                    coordinates[0] + "-" + coordinates[1]);
                        }
                    }
                }
            } else if (operationFeature.geometry() instanceof MultiLineString) {
                MultiLineString multiLineString = (MultiLineString) operationFeature.geometry();
                List<Point> points = multiLineString.coordinates().get(coordinatesIndex[0]);

                int i = Integer.parseInt(indexs[0]);
                int j = Integer.parseInt(indexs[1]);

                if (i == coordinatesIndex[0]) {

                    if (coordinatesIndex[1] == points.size() && j == 1) {
                        //删除的是最后一个，则更新第一个新增点的图标
                        shouldUpdateSymbol.add(symbol);
                    } else {
                        //大于J的索引才需要更新
                        if (j == coordinatesIndex[1]) {
                            shouldRemoveSymbol.add(symbol);
                        } else if (j > coordinatesIndex[1]) {
                            if (j == coordinatesIndex[1] + 1) {
                                //更新图标位置到中线点
                                shouldUpdateSymbol.add(symbol);
                            }
                            coordinates[1] = coordinates[1] - 1;

                            data.addProperty(CommonPointHelper.KEY_POINT_INDEXS,
                                    coordinates[0] + "-" + coordinates[1]);
                        }
                    }
                }
            } else if (operationFeature.geometry() instanceof LineString) {
                LineString lineString = (LineString) operationFeature.geometry();
                List<Point> points = lineString.coordinates();

                int i = Integer.parseInt(indexs[0]);
                if (coordinatesIndex[0] == points.size() && i == 1) {
                    //删除的是最后一个，则更新第一个新增点的图标
                    shouldUpdateSymbol.add(symbol);
                } else {
                    //大于J的索引才需要更新
                    if (i == coordinatesIndex[0]) {
                        shouldRemoveSymbol.add(symbol);
                    } else if (i > coordinatesIndex[0]) {
                        if (i == coordinatesIndex[0] + 1) {
                            //更新图标位置到中线点
                            shouldUpdateSymbol.add(symbol);
                        }
                        coordinates[0] = coordinates[0] - 1;

                        data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(coordinates[0]));
                    }
                }
            }

        }
        symbolManager.delete(shouldRemoveSymbol);
        addPointSymbolList.removeAll(shouldRemoveSymbol);

        for (Symbol symbol : shouldUpdateSymbol) {
            JsonObject data = (JsonObject) symbol.getData();
            String indexStr = data.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString();
            String[] indexs = indexStr.split("-");

            int[] coordinates = new int[indexs.length];
            for (int i = 0; i < indexs.length; i++) {
                coordinates[i] = Integer.parseInt(indexs[i]);
            }

            if (operationFeature.geometry() instanceof MultiPolygon) {
                int index = coordinates[2];
                List<Point> points = ((MultiPolygon) operationFeature.geometry()).coordinates()
                        .get(coordinates[0])
                        .get(coordinates[1]);
                Point point = points.get(index);
                Point prePoint = points.get(index - 1);
                symbol.setLatLng(new LatLng(
                        (point.latitude() + prePoint.latitude()) / 2,
                        (point.longitude() + prePoint.longitude()) / 2));
                updateSymbol(symbol);
            } else if (operationFeature.geometry() instanceof Polygon) {
                int index = coordinates[1];
                List<Point> points = ((Polygon) operationFeature.geometry()).coordinates()
                        .get(coordinates[0]);

                Point point = points.get(index);
                Point prePoint = points.get(index - 1);
                symbol.setLatLng(new LatLng(
                        (point.latitude() + prePoint.latitude()) / 2,
                        (point.longitude() + prePoint.longitude()) / 2));
                updateSymbol(symbol);
            } else if (operationFeature.geometry() instanceof MultiLineString) {
                int index = coordinates[1];
                List<Point> points = ((MultiLineString) operationFeature.geometry()).coordinates()
                        .get(coordinates[0]);

                Point point = points.get(index);
                Point prePoint = points.get(index - 1);
                symbol.setLatLng(new LatLng(
                        (point.latitude() + prePoint.latitude()) / 2,
                        (point.longitude() + prePoint.longitude()) / 2));
                updateSymbol(symbol);
            } else if (operationFeature.geometry() instanceof LineString) {
                int index = coordinates[0];
                List<Point> points = ((LineString) operationFeature.geometry()).coordinates();

                Point point = points.get(index);
                Point prePoint = points.get(index - 1);
                symbol.setLatLng(new LatLng(
                        (point.latitude() + prePoint.latitude()) / 2,
                        (point.longitude() + prePoint.longitude()) / 2));
                updateSymbol(symbol);
            }
        }

        //更新公共点坐标
        List<CommonPointHelper.CommonPoint> points = commonPointHelper.getFeatureCommonPoint(targetFeatureId);
        if (points.size() > 0) {
            for (CommonPointHelper.CommonPoint point : points) {
                int[] pointCoordinates = point.getCoordinatesIndex();

                if (operationFeature.geometry() instanceof MultiPolygon) {
                    int i = pointCoordinates[0];
                    int j = pointCoordinates[1];
                    int k = pointCoordinates[2];

                    if (i == coordinatesIndex[0] && j == coordinatesIndex[1]
                            && k > coordinatesIndex[2]) {
                        pointCoordinates[2] = pointCoordinates[2] - 1;
                        point.setCoordinatesIndex(pointCoordinates);
                    }
                } else if (operationFeature.geometry() instanceof Polygon) {
                    int i = pointCoordinates[0];
                    int j = pointCoordinates[1];

                    if (i == coordinatesIndex[0] && j > coordinatesIndex[1]) {
                        //大于J的索引才需要更新
                        pointCoordinates[1] = pointCoordinates[1] - 1;
                        point.setCoordinatesIndex(pointCoordinates);
                    }
                } else if (operationFeature.geometry() instanceof MultiLineString) {
                    int i = pointCoordinates[0];
                    int j = pointCoordinates[1];

                    if (i == coordinatesIndex[0] && j > coordinatesIndex[1]) {
                        //大于J的索引才需要更新
                        pointCoordinates[1] = pointCoordinates[1] - 1;
                        point.setCoordinatesIndex(pointCoordinates);
                    }
                } else if (operationFeature.geometry() instanceof LineString) {
                    int i = pointCoordinates[0];

                    if (i > coordinatesIndex[0]) {
                        //大于J的索引才需要更新
                        pointCoordinates[0] = pointCoordinates[0] - 1;
                        point.setCoordinatesIndex(pointCoordinates);
                    }
                }
            }

        }

        return true;
    }

    //判断该点能否删除
    boolean canDeleteGeometryPointDataIndexs(String targetFeatureId, int[] coordinatesIndex) {
        //找到操作的Feature
        Feature operationFeature = getEditFeature(targetFeatureId);
        if (operationFeature != null) {
            if (operationFeature.geometry() instanceof MultiPolygon) {
                MultiPolygon multiPolygon = (MultiPolygon) operationFeature.geometry();
                int i = coordinatesIndex[0];
                int j = coordinatesIndex[1];

                List<Point> points = multiPolygon.coordinates().get(i).get(j);
                //不能继续删除了，不然无法构成多边形
                if (points.size() > 4) {
                    return true;
                }
            } else if (operationFeature.geometry() instanceof Polygon) {
                Polygon polygon = (Polygon) operationFeature.geometry();
                int i = coordinatesIndex[0];

                List<Point> points = polygon.coordinates().get(i);
                //不能继续删除了，不然无法构成多边形
                if (points.size() > 4) {
                    return true;
                }
            } else if (operationFeature.geometry() instanceof MultiLineString) {
                MultiLineString multiLineString = (MultiLineString) operationFeature.geometry();
                int i = coordinatesIndex[0];
                List<Point> points = multiLineString.coordinates().get(i);
                //不能继续删除了，不然无法构成线
                if (points.size() > 2) {
                    return true;
                }

            } else if (operationFeature.geometry() instanceof LineString) {
                LineString lineString = (LineString) operationFeature.geometry();
                List<Point> points = lineString.coordinates();
                //不能继续删除了，不然无法构成线
                if (points.size() > 2) {
                    return true;
                }
            } else if (operationFeature.geometry() instanceof MultiPoint) {
                MultiPoint multiPoint = (MultiPoint) operationFeature.geometry();
                List<Point> points = multiPoint.coordinates();
                //不能继续删除了，不然无法构成点
                if (points.size() > 1) {
                    return true;
                }
            } else if (operationFeature.geometry() instanceof Point) {
                return false;
            }
        }
        return false;
    }

    BianjieHistory updateGeometryCoordinatesLatlng(String featureId, int[] coordinatesIndex, LatLng newLatlng, boolean updateTargetSymbol) {
        BianjieHistory bianjieHistory = updateGeometryCoordinatesLatlng(featureId, coordinatesIndex, newLatlng);
        if (updateTargetSymbol) {
            //更新标点
            doTimeObservable(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    Symbol symbol = getTargetPointSymbol(featureId, coordinatesIndex);
                    if (symbol != null) {
                        symbol.setLatLng(newLatlng);
                        updateSymbol(symbol);
                    }
                }
            });
        }
        return bianjieHistory;
    }

    BianjieCommonHistory updateGeometryCoordinatesLatlng(LatLng newLatlng, String commonKey) {
        //说明是公共点
        Set<CommonPointHelper.CommonPoint> commonPointSet =
                commonPointHelper.getCommonPoint(commonKey);
        List<BianjieHistory> historyList = new ArrayList<>();
        if (commonPointSet != null) {
            for (CommonPointHelper.CommonPoint commonPoint : commonPointSet) {
                BianjieHistory bianjieHistory = updateGeometryCoordinatesLatlng(commonPoint.getFeatureId(),
                        commonPoint.getCoordinatesIndex(), newLatlng);
                historyList.add(bianjieHistory);
            }
        }

        return new BianjieCommonHistory(BianjieHistory.Type.MovePoint, historyList);
    }

    //更新图形点坐标
    BianjieHistory updateGeometryCoordinatesLatlng(String featureId, int[] coordinatesIndex, LatLng newLatlng) {
        //找到操作的Feature
        Feature operationFeature = getEditFeature(featureId);

        Point oldPoint = null;
        Point newPoint = Point.fromLngLat(newLatlng.getLongitude(),
                newLatlng.getLatitude());

        if (operationFeature.geometry() instanceof MultiPolygon) {
            MultiPolygon multiPolygon = (MultiPolygon) operationFeature.geometry();
            int i = coordinatesIndex[0];
            int j = coordinatesIndex[1];
            int k = coordinatesIndex[2];

            List<Point> points = multiPolygon.coordinates().get(i).get(j);
            oldPoint = points.get(k);

            points.set(k, newPoint);

            //多边形闭合需要重置第一个点和最后一个点
            if (k == 0) {
                points.set(points.size() - 1, newPoint);
            } else if (k == points.size() - 1) {
                points.set(0, newPoint);
            }

        } else if (operationFeature.geometry() instanceof Polygon) {
            Polygon polygon = (Polygon) operationFeature.geometry();
            int i = coordinatesIndex[0];
            int j = coordinatesIndex[1];

            List<Point> points = polygon.coordinates().get(i);

            oldPoint = points.get(j);
            points.set(j, newPoint);

            //多边形闭合需要重置第一个点和最后一个点
            if (j == 0) {
                points.set(points.size() - 1, newPoint);
            } else if (j == points.size() - 1) {
                points.set(0, newPoint);
            }

        } else if (operationFeature.geometry() instanceof MultiLineString) {
            MultiLineString multiLineString = (MultiLineString) operationFeature.geometry();
            int i = coordinatesIndex[0];
            int j = coordinatesIndex[1];

            List<Point> points = multiLineString.coordinates().get(i);

            oldPoint = points.get(j);
            points.set(j, newPoint);
        } else if (operationFeature.geometry() instanceof LineString) {
            LineString lineString = (LineString) operationFeature.geometry();
            int i = coordinatesIndex[0];

            List<Point> points = lineString.coordinates();

            oldPoint = points.get(i);
            points.set(i, newPoint);
        } else if (operationFeature.geometry() instanceof MultiPoint) {
            MultiPoint multiPoint = (MultiPoint) operationFeature.geometry();
            int i = coordinatesIndex[0];

            List<Point> points = multiPoint.coordinates();

            oldPoint = points.get(i);
            points.set(i, newPoint);
        } else if (operationFeature.geometry() instanceof Point) {
            Point point = (Point) operationFeature.geometry();

            oldPoint = Point.fromLngLat(point.longitude(), point.latitude());

            newPoint = Point.fromLngLat(newLatlng.getLongitude(),
                    newLatlng.getLatitude());
            //设置longitude
            point.coordinates().set(0, newPoint.longitude());
            //设置latitude
            point.coordinates().set(1, newPoint.latitude());
        }
        return new BianjieHistory(
                BianjieHistory.Type.MovePoint,
                featureId,
                coordinatesIndex,
                oldPoint, newPoint);
    }

    void updateTargetSymbolLatLng(String featureId, int[] coordinatesIndex, LatLng newLatlng) {
        //更新标点
        doTimeObservable(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) throws Exception {
                Symbol symbol = getTargetPointSymbol(featureId, coordinatesIndex);
                if (symbol != null) {
                    symbol.setLatLng(newLatlng);
                    updateSymbol(symbol);
                }
            }
        });
    }

    @SuppressLint("CheckResult")
    void updateGeometryPointSymbolOnBianjieMove(Feature operationFeature, int[] coordinatesIndex) {
        doTimeObservable(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) throws Exception {
                String targetFeatureId = operationFeature.getStringProperty(getFeatureIdKey());
                //更新插入Symbol
                List<Symbol> shouldUpdateSymbol = new ArrayList<>();
                for (Symbol symbol : addPointSymbolList) {
                    JsonObject data = (JsonObject) symbol.getData();
                    String featureId = data.get(getFeatureIdKey()).getAsString();

                    if (!targetFeatureId.equals(featureId)) {
                        continue;
                    }

                    String indexStr = data.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString();
                    String[] indexs = indexStr.split("-");

                    if (coordinatesIndex.length > 2) {
                        int i = Integer.parseInt(indexs[0]);
                        int j = Integer.parseInt(indexs[1]);
                        int k = Integer.parseInt(indexs[2]);

                        if (i == coordinatesIndex[0] && j == coordinatesIndex[1]) {
                            if (k == coordinatesIndex[2] || k == coordinatesIndex[2] + 1) {
                                shouldUpdateSymbol.add(symbol);
                            } else if (k == 1 && coordinatesIndex[2] == addPointSymbolList.size()) {
                                shouldUpdateSymbol.add(symbol);
                            }
                        }
                    } else if (coordinatesIndex.length > 1) {
                        int i = Integer.parseInt(indexs[0]);
                        int j = Integer.parseInt(indexs[1]);

                        if (i == coordinatesIndex[0]) {
                            //大于J的索引才需要更新
                            if (j == coordinatesIndex[1] || j == coordinatesIndex[1] + 1) {
                                shouldUpdateSymbol.add(symbol);
                            } else if (j == 1 && coordinatesIndex[1] == addPointSymbolList.size()) {
                                shouldUpdateSymbol.add(symbol);
                            }
                        }
                    } else if (coordinatesIndex.length > 0) {
                        int i = Integer.parseInt(indexs[0]);

                        //大于的索引才需要更新
                        if (i == coordinatesIndex[0] || i == coordinatesIndex[0] + 1) {
                            shouldUpdateSymbol.add(symbol);
                        }

                    }
                }

                for (Symbol symbol : shouldUpdateSymbol) {

                    JsonObject data = (JsonObject) symbol.getData();
                    String featureId = data.get(getFeatureIdKey()).getAsString();

                    if (!targetFeatureId.equals(featureId)) {
                        continue;
                    }

                    String indexStr = data.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString();
                    String[] indexs = indexStr.split("-");

                    int[] coordinates = new int[indexs.length];
                    for (int i = 0; i < indexs.length; i++) {
                        coordinates[i] = Integer.parseInt(indexs[i]);
                    }

                    LatLng centerPoint = null;
                    if (operationFeature.geometry() instanceof MultiPolygon) {
                        MultiPolygon multiPolygon = (MultiPolygon) operationFeature.geometry();

                        List<Point> points = multiPolygon.coordinates()
                                .get(coordinates[0])
                                .get(coordinates[1]);

                        Point firstPoint = points.get(coordinates[2] - 1);
                        Point secondPoint = points.get(coordinates[2]);
                        centerPoint = new LatLng(
                                (firstPoint.latitude() + secondPoint.latitude()) / 2,
                                (firstPoint.longitude() + secondPoint.longitude()) / 2);

                    } else if (operationFeature.geometry() instanceof Polygon) {
                        Polygon polygon = (Polygon) operationFeature.geometry();
                        List<Point> points = polygon.coordinates()
                                .get(coordinates[0]);

                        Point firstPoint = points.get(coordinates[1] - 1);
                        Point secondPoint = points.get(coordinates[1]);
                        centerPoint = new LatLng(
                                (firstPoint.latitude() + secondPoint.latitude()) / 2,
                                (firstPoint.longitude() + secondPoint.longitude()) / 2);
                    } else if (operationFeature.geometry() instanceof MultiLineString) {
                        MultiLineString multiLineString = (MultiLineString) operationFeature.geometry();
                        List<Point> points = multiLineString.coordinates()
                                .get(coordinates[0]);

                        Point firstPoint = points.get(coordinates[1] - 1);
                        Point secondPoint = points.get(coordinates[1]);
                        centerPoint = new LatLng(
                                (firstPoint.latitude() + secondPoint.latitude()) / 2,
                                (firstPoint.longitude() + secondPoint.longitude()) / 2);

                    } else if (operationFeature.geometry() instanceof LineString) {
                        LineString lineString = (LineString) operationFeature.geometry();
                        List<Point> points = lineString.coordinates();

                        Point firstPoint = points.get(coordinates[0] - 1);
                        Point secondPoint = points.get(coordinates[0]);
                        centerPoint = new LatLng(
                                (firstPoint.latitude() + secondPoint.latitude()) / 2,
                                (firstPoint.longitude() + secondPoint.longitude()) / 2);
                    } else if (operationFeature.geometry() instanceof MultiPoint) {
                        MultiPoint multiPoint = (MultiPoint) operationFeature.geometry();
                        List<Point> points = multiPoint.coordinates();

                        Point firstPoint = points.get(coordinates[0] - 1);
                        Point secondPoint = points.get(coordinates[0]);
                        centerPoint = new LatLng(
                                (firstPoint.latitude() + secondPoint.latitude()) / 2,
                                (firstPoint.longitude() + secondPoint.longitude()) / 2);
                    }
                    if (centerPoint != null) {
                        symbol.setLatLng(centerPoint);
                        updateSymbol(symbol);
                    }
                }
            }
        });
    }

    private Symbol getTargetPointSymbol(String targetFeatureId, int[] coordinatesIndex) {
        for (Symbol symbol : symbolList) {
            JsonObject data = (JsonObject) symbol.getData();
            String featureId = data.get(getFeatureIdKey()).getAsString();

            if (!targetFeatureId.equals(featureId)) {
                continue;
            }

            String indexStr = data.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString();
            String[] indexs = indexStr.split("-");

            int[] coordinates = new int[indexs.length];
            for (int i = 0; i < indexs.length; i++) {
                coordinates[i] = Integer.parseInt(indexs[i]);
            }


            if (coordinatesIndex.length > 2) {
                int i = Integer.parseInt(indexs[0]);
                int j = Integer.parseInt(indexs[1]);
                int k = Integer.parseInt(indexs[2]);

                if (i == coordinatesIndex[0] && j == coordinatesIndex[1] && k == coordinatesIndex[2]) {
                    return symbol;
                }

            } else if (coordinatesIndex.length > 1) {
                int i = Integer.parseInt(indexs[0]);
                int j = Integer.parseInt(indexs[1]);

                if (i == coordinatesIndex[0] && j == coordinatesIndex[1]) {
                    return symbol;
                }
            } else if (coordinatesIndex.length > 0) {
                int i = Integer.parseInt(indexs[0]);
                if (i == coordinatesIndex[0]) {
                    return symbol;
                }
            }

        }
        return null;
    }

    //根据targetFeatureId和coordinatesIndex索引找到目标Symbol
    private Symbol getTargetAddPointSymbol(String targetFeatureId, int[] coordinatesIndex) {
        for (Symbol symbol : addPointSymbolList) {
            JsonObject data = (JsonObject) symbol.getData();
            String featureId = data.get(getFeatureIdKey()).getAsString();

            if (!targetFeatureId.equals(featureId)) {
                continue;
            }

            String indexStr = data.get(CommonPointHelper.KEY_POINT_INDEXS).getAsString();
            String[] indexs = indexStr.split("-");

            int[] coordinates = new int[indexs.length];
            for (int i = 0; i < indexs.length; i++) {
                coordinates[i] = Integer.parseInt(indexs[i]);
            }


            if (coordinatesIndex.length > 2) {
                int i = Integer.parseInt(indexs[0]);
                int j = Integer.parseInt(indexs[1]);
                int k = Integer.parseInt(indexs[2]);

                if (i == coordinatesIndex[0] && j == coordinatesIndex[1] && k == coordinatesIndex[2]) {
                    return symbol;
                }

            } else if (coordinatesIndex.length > 1) {
                int i = Integer.parseInt(indexs[0]);
                int j = Integer.parseInt(indexs[1]);

                if (i == coordinatesIndex[0] && j == coordinatesIndex[1]) {
                    return symbol;
                }
            } else if (coordinatesIndex.length > 0) {
                int i = Integer.parseInt(indexs[0]);
                ;
                if (i == coordinatesIndex[0]) {
                    return symbol;
                }
            }

        }
        return null;
    }

    //生成节点
    void createSymbol(LatLng latLng, int index) {
        JsonObject jsonData = new JsonObject();
        jsonData.addProperty(KEY_SYMBOL_TYPE, TYPE_SYMBOL_POINT);
        jsonData.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(index));
        Symbol symbol = createSymbol(ICON_MAP_POINT, latLng, jsonData);
        symbolList.add(symbol);
    }

    void addCommonPoint(BianjieCommonHistory commonHistory) {
        //添加到公共点存储中
        for (BianjieHistory bianjieHistory : commonHistory.getBianjieHistories()) {

            JsonObject data = new JsonObject();

            int[] coordinates = bianjieHistory.getCoordinatesIndex();
            if (coordinates.length > 2) {
                data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, coordinates[0] + "-"
                        + coordinates[1] + "-" + coordinates[2]);
            } else if (coordinates.length > 1) {
                data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, coordinates[0] + "-"
                        + coordinates[1]);
            } else if (coordinates.length > 0) {
                data.addProperty(CommonPointHelper.KEY_POINT_INDEXS, Integer.toString(coordinates[0]));
            }
            data.addProperty(getFeatureIdKey(), bianjieHistory.getFeatureTempId());
            commonPointHelper.addCommonPoint(commonHistory.getCommonKey(), data);
        }
    }

    Set<CommonPointHelper.CommonPoint> removeCommonPoint(String commonKey) {
        return commonPointHelper.removeCommonPoint(commonKey);
    }


    public List<Symbol> getSymbolList() {
        return symbolList;
    }


    private Symbol createSymbol(String iconType, LatLng latLng, JsonObject data) {
        return symbolManager.create(createSymbolOptions(iconType, latLng, data));
    }

    private SymbolOptions createSymbolOptions(String iconType, LatLng latLng, JsonObject data) {
        return new SymbolOptions()
                .withLatLng(latLng)
                .withIconImage(iconType)
                .withSymbolSortKey(2f)
                .withIconSize(1f)
                .withData(data)
                .withTextColor("#ffffff")
                .withTextSize(12f)
                .withTextOffset(new Float[]{0f, 1.2f})
                .withTextField(data.getAsJsonPrimitive(CommonPointHelper.KEY_POINT_INDEXS).getAsString())
                .withDraggable(true);
    }

    void updateSymbol(Symbol symbol) {
        JsonElement jsonElement = symbol.getData();
        if (jsonElement.isJsonObject()) {
            JsonObject data = (JsonObject) jsonElement;
            symbol.setTextField(data.getAsJsonPrimitive(CommonPointHelper.KEY_POINT_INDEXS).getAsString());
        }
        symbolManager.update(symbol);
    }

    void clearCommonPointData() {
        commonPointHelper.clear();
    }

    void clearPointSymbol() {
        symbolManager.delete(symbolList);
        symbolList.clear();
    }

    void clearAllSymbol() {
        symbolManager.delete(symbolList);
        symbolList.clear();

        symbolManager.delete(addPointSymbolList);
        addPointSymbolList.clear();
    }


    @SuppressLint("CheckResult")
    private void doTimeObservable(Consumer<Long> consumer) {
        Observable.timer(10, TimeUnit.MILLISECONDS)
                .compose(opManager.getBaseView().bindToLifecycle())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(consumer);
    }


    public interface OnAddBianjieFeatureSymbolPointListener {

        void onLoadSuccess();

    }


    void release() {
        this.symbolManager = null;
        this.symbolList = null;
        this.addPointSymbolList = null;
        this.commonPointHelper = null;
    }

}